How do I set Vim options on a per-file basis without changing my vimrc?
Answer
vim: set ts=2 sw=2 :
Explanation
A modeline is a special comment embedded in a file that Vim reads to apply file-specific settings automatically. When Vim opens a file, it scans the first and last few lines for a modeline pattern and applies any options it finds. This lets you enforce consistent formatting (tabs, indentation, textwidth, etc.) for individual files regardless of each contributor's vimrc.
How it works
- Add a comment near the top or bottom of your file in the format:
vim: set {options} : - Vim checks the first and last
modelineslines of the file (default: 5 lines) - Any recognized Vim option in the modeline is applied as a local setting for that buffer
- The modeline must appear inside a valid comment for the file's language to avoid syntax errors
Modeline formats
Vim recognizes two modeline styles:
// vim: set ts=4 sw=4 expandtab :
or the shorter form:
// vim: ts=4 sw=4 expandtab
The first form uses set and ends with a colon. The second form omits set and ends at the end of the line.
Example
A Python file with 2-space indentation enforced by modeline:
# mymodule.py
# vim: set ts=2 sw=2 expandtab :
def greet(name):
print(f"Hello, {name}")
A JavaScript file at the bottom:
function main() {
return 42;
}
// vim: ts=2 sw=2 expandtab
A Makefile that must use real tabs:
# vim: set noexpandtab ts=8 sw=8 :
all:
echo "building"
Tips
- Modelines must be within the first or last N lines, controlled by
:set modelines=5(default is 5) - Modelines must be enabled:
:set modeline(it is on by default in most Vim builds, but disabled for root) - Not all options can be set via modeline for security reasons — options like
shell,makeprg, andgrepprgare blocked unless you:set secureis off - Common modeline options:
ts(tabstop),sw(shiftwidth),sts(softtabstop),et(expandtab),tw(textwidth),ft(filetype),ff(fileformat),fenc(fileencoding) - Use
ft=pythonin a modeline to force Vim's filetype detection when the extension is nonstandard or missing - Many open-source projects use modelines to ensure consistent formatting across contributors without requiring everyone to adjust their vimrc
- EditorConfig is a modern cross-editor alternative, but modelines are Vim-native and require zero plugins