How do I automatically detect and match a file's indentation settings in Vim?
Answer
vim-sleuth
Explanation
The vim-sleuth plugin by Tim Pope automatically detects the indentation style (tabs vs spaces) and width used in a file and sets shiftwidth, expandtab, tabstop, and softtabstop accordingly. Instead of manually configuring indentation per project or constantly running :set expandtab shiftwidth=2, sleuth examines the file content and surrounding files to figure out the correct settings for you.
The problem
Every project has its own indentation conventions. One project uses 2-space indentation, another uses 4 spaces, a third uses tabs. Without sleuth, you either:
- Set a single global default and fight it when switching projects
- Add modelines to every file
- Maintain per-project
.vimrcfiles or EditorConfig setups - Manually run
:set shiftwidth=X expandtabevery time you open a file with different conventions
Vim-sleuth eliminates all of this by detecting the correct settings automatically.
How it works
When you open a file, sleuth:
- Examines the file's content — it looks at the leading whitespace of each line to determine whether the file uses tabs or spaces, and what the indentation width is
- Checks neighboring files — if the current file is new or empty, sleuth looks at other files in the same directory with the same extension to infer the project's convention
- Sets buffer-local options — it applies
shiftwidth,expandtab,tabstop, andsofttabstopto the current buffer only, leaving your global settings untouched
What gets configured
shiftwidth " number of spaces for each indent level (>>, <<, ==)
expandtab " whether to use spaces (on) or tabs (off) when pressing Tab
tabstop " how wide a tab character displays
softtabstop " how many spaces a Tab keypress inserts
All four options are set as buffer-local values, so different buffers can have different indentation settings simultaneously.
Zero configuration
Sleuth requires no setup at all. Install it and it works immediately:
" That's it. No configuration needed.
" Just install the plugin and open files.
Your global vimrc settings remain as the fallback for new files or files where sleuth cannot determine the style.
Verifying what sleuth detected
Run :verbose set shiftwidth? expandtab? to see the current values and where they were set. If sleuth is active, it will show the values were set by the sleuth plugin:
:verbose set shiftwidth? expandtab?
shiftwidth=4
Last set from ~/.vim/pack/plugins/start/vim-sleuth/plugin/sleuth.vim
expandtab
Last set from ~/.vim/pack/plugins/start/vim-sleuth/plugin/sleuth.vim
How it handles edge cases
- Mixed indentation: sleuth picks the dominant style in the file
- Empty files: sleuth examines sibling files with the same extension
- Files with modelines: Vim modelines take precedence over sleuth
- EditorConfig: if you use editorconfig, those settings take precedence — sleuth gracefully defers
Tips
- Sleuth is a "set and forget" plugin — once installed, you never think about indentation settings again
- It works alongside EditorConfig: sleuth only sets values that EditorConfig has not already configured
- The plugin is extremely lightweight — under 200 lines of code with no dependencies
- Pair with
set autoindent(which Vim 8+ enables by default) for complete automatic indentation handling - If sleuth detects the wrong settings for a specific file, you can always override with a modeline at the top or bottom of the file:
" vim: set ts=4 sw=4 expandtab: - Works with both Vim and Neovim with no additional configuration