I've been using vi-based editors since the late 80s. While an.exrc – or, as I eventually settled onvim as myvi-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 alongswaths 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 ofvim 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 tolegibly extend mapping of file-suffixes to file types. This is done by using a grouping-block to applyautocmd-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 yamlau! BufRead,BufNewFile *.yaml setfiletype yaml
The latter line-pair captures YAML files that might be suffixed.ymlor.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 thebash 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 charactersset wrapset textwidth=80set wrapmargin=0"Ensure linewraps happen when textwidth is reachedset formatoptions+=t"Enable auto-indentset autoindent"Set 4-char tabstopsset tabstop=4"Convert tabs to spacesset expandtab"Set autoindent to 4-charsset shiftwidth=4"Eliminate trailing whitespaceaugroup prewrites autocmd! autocmd BufWritePre,FileWritePre * :%s/\s\+$//e | %s/\r$//eaugroup 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-highlightingsyntax off"Turn off search-highlightingset nohlsearch"Turn off angry fruit-saladset t_Co=0
I, uh, hate the "angry fruit-salad" appearance that many distro's default vim-configs use.