An auto command is appropriate here...
autocmd BufReadPost * if line('$') > 150 | :setlocal number | else | :setlocal nonumber | endif
OR, you can use this nice enhancement care of MartinTournoij. It has the same result but takes up a lot less space:
autocmd BufReadPost * let &l:number = line('$') > 150
Explanation: First, &l:number
is a synonym, if you will, of the setting altered by setlocal number
. The conditional line('$') > 150
returns, essentially, either true or false. Since 'number'
should be set to true or false also we can just do a direct assignment to it from the conditional result let &l:number = ...
.
Either way, this autocommand approach accomplishes a few things...
- Ensures a check is made after any buffer is loaded (when number of lines is known!).
- Uses the buffer-specific setting rather than the global setting.
- Explicitly enables or disables as appropriate to ensure correct setting.
Note that if a file has a modeline that sets/unsets line numbers that has priority and will override this.
If you've not used auto commands before they usually go in your init.vim file. You should enclose them in an auto command group like this...
augroup InitVimAutocmds
au!
[auto commands go here]
augroup END
This ensures they don't get entered multiple times if you reload init.vim.
Update: I don't know if you were thinking about this but it's worth pointing out (another nod to MartinTournoij) that this is static, i.e. the line numbering is determined upon buffer load and if you subsequently surpass or drop below 150 lines nothing will change. It is definitely possible to extend this so it's dynamic. If that's something you're interested in let me know.