In most cases, I want to use the same setting. However, when I write the makefile file, I need to use tab instead of space, so I need to execute the :set noexpandtab for all the makefile file. In order to simplify this process, I want to write this to .vimrc, but I don't know how to execute this command according to the name of the file being edited.

  • Another option would be to change the syntax file of make files – eyal karni Dec 15 '19 at 12:46

As I have written about extensively, the vim technique for this type of thing is called an ftplugin, which stands for filetype-plugin. What that means is that certain filetypes have different settings than others. make is one such filetype.

Vim comes with a set of filetype detecters that are enabled when you do

:filetype on

However, you can ask vim to load any filetype-specific plugin code (which can be arbitrarily awesome!) and indent code with

:filetype plugin indent on

Most vim users I know have this command in their vimrc.

Finally, the default ftplugin for makefiles sets noexpandtab, I believe. If not, you can place

setlocal noexpandtab

in your personal vim ftplugin for make, which typically lives at ~/.vim/after/ftplugin/make.vim (though other names are possible). The setlocal version makes the change unique to that buffer, which means all make buffers.

Why not auto-commands? Because it’s vimrc clutter and because vim already has autocommands that fire on a Filetype—and all they do is source the appropriate runtime files. It’s inelegant not to use this mechanism. It separates out my filetype settings so I can quickly focus on only what I need.

Since we're doing "vim proper," I am obligated to also mention b:undo_ftplugin—it is executed if the filetype changes, so you generally want it to be properly set. If you don't switch filetypes, no harm done, but to be on the safe side:

" Don't forget to add to 'b:undo_ftplugin'
" I've got a specialized framework for that over at
" https://github.com/benknoble/Dotfiles/blob/master/links/vim/autoload/ftplugin.vim
" but this is simpler and should work for your purpose
let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
if ! empty(b:undo_ftplugin)
  let b:undo_ftplugin .= ' | '
let b:undo_ftplugin .= 'setlocal expandtab<'
| improve this answer | |
  • 1
    Do you think you might want to mention b:undo_ftplugin in your answer? (Unfortunately that complicates things and is only relevant when you switch filetype of an existing buffer, so not often... But still mentioning might be worth it.) – filbranden Dec 15 '19 at 16:22
  • 1
    @filbranden I'll mention it briefly. Was yours the second upvote? If so, thanks for the 6k ;) – D. Ben Knoble Dec 15 '19 at 16:22
  • 1
    Congrats! Great milestone! It's a great answer, I was hoping ftplugin was going to be mentioned in an answer here, it's definitely the right approach. I'm really glad that it was. – filbranden Dec 15 '19 at 16:25
  • I've never ever defined b:undo_ftplugin in my numerous ftplugins as I've never needed to switch the filetype of my buffers. However, even if I tend to disagree with b:did_ftplugin for non-standard ftplugins, it starts to have its use when dealing with settings that are usually set in standard ftplugins like the one for Makefiles. – Luc Hermitte Dec 16 '19 at 13:10
  • @LucHermitte sorry, huh? I follow you on undo_ftplugin (though I have in fact needed it before). But for the other... do you mean it’s useful in non-after directories to stop vim’s runtime files? In general, I dont want that; I’d rather override them afterwards then disable them completely, because im customizing. Im just not following why you mentioned it/what you mean. Are there improvements you think could be made? – D. Ben Knoble Dec 16 '19 at 13:37

You can use autocmd for this. First run the following command to know the FileType (while your makefile is open) -

:set filetype?

This will show you the filetype. Then you can put the following in your vimrc to set settings for specifice fitetype like this -

augroup makefilesettings
    autocmd FileType makefile setlocal noexpandtab
augroup END
| improve this answer | |
  • 2
    There are better options than auto commands, though I was sure the default ftplugin for make set this – D. Ben Knoble Dec 15 '19 at 14:22

You can simply put this in your .vimrc:

if expand('%:t')=="Makefile"
" do your stuff
| improve this answer | |
  • 2
    This won't work. .vimrc is loaded only once. When we open other files from the current session (:edit, :sp...), it isn't reloaded, and the check won't be applied to the new files. The only way that works is to rely on events, and the way that scales consists in using filetypes plugins. Moreover, Makefile are already correctly managed (and do what the OP is looking for) as long as ftplugins are activated in the .vimrc as D. Ben Knoble explained. – Luc Hermitte Dec 16 '19 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.