i am setting the default vim-statusline, and i made this line on my colorscheme:

hi MyStatusLineDevIcon ctermfg=7 ctermbg=0 cterm=NONE

So i can color the devicons on my statusline.vim config

I call them using this function:

function! ShowDevIcons()
  return WebDevIconsGetFileTypeSymbol()

And set it on the statusline using this:

set statusline+=%#MyStatuslineDevIcon#\

Now, the settings are all working fine, the ctermfg value i put on my colorscheme changes the icons alright.

But i want to make a function to change the devicon based on the filetype, like this:

function! SetFiletype()
  let l:filetype = &filetype

  if l:filetype == "vim"
  autocmd BufEnter * hi MyStatuslineDevIcon ctermbg=8 cterm=bold ctermfg=3

But i can't make it work. It returns no errors but it doesn't change the color. If i enter the hi MyStatuslineDevIcon ctermbg=8 cterm=bold ctermfg=3 command manually, it does the job, but the function is not working. Any help, please?

  • 1
    Dont use autocmd! without an augroup! (The first bang is part of the command; the second is for emphasis.)
    – D. Ben Knoble
    Dec 7 '20 at 13:20
  • 2
    Welcome to Vi and Vim!
    – filbranden
    Dec 7 '20 at 23:24

There are some issues with the approach you described.

First, you are calling autocmd! outside of an augroup. This is really bad, since it's actually erasing all auto-commands!

Second, the logic in SetFiletype() looks odd, since it's first checking whether the file type is "vim" and then creating an auto-command to set the highlight group when entering a buffer (any buffer.)

If what you wanted to accomplish is to change the highlight group every time you enter a buffer with a specific filetype, it would make more sense to invert this approach, and have a fixed autocmd to call a function when you enter a buffer, and then in that function check for the &filetype and act appropriately. (You might also want to reset back to the original highlight group if you're entering a buffer of a different file type.)

For example:

function! SetMyStatusLineDevIconHighlight()
  if &filetype ==# 'vim'
    hi MyStatusLineDevIcon ctermbg=8 cterm=bold ctermfg=3
    hi MyStatusLineDevIcon ctermfg=7 ctermbg=0 cterm=NONE

augroup MyStatusLineDevIconGroup
  autocmd BufEnter * call SetMyStatusLineDevIconHighlight()
augroup END

This will work... But it will probably not do what you want. You see, highlight groups are actually global in Vim and Vim will use the same one for every window you have. So if you have split windows and in one of them you're editing a file of type "vim", but in the other you're editing a file of a different type, Vim will always switch the status line of all windows to the highlight of the window you're currently in. So when you switch from a "vim" window to a non-"vim" window or vice-versa, Vim will switch them all.

There are ways to set the 'statusline' so that it takes the status of the current window (such as the file type of the buffer being edited there) in consideration, such as:

  • Using :setlocal to set a local 'statusline' setting for that specific window. You could set that in an autocmd for the WinEnter event, or even perhaps on one for a FileType event, then use a specific highlight for the filetype.
  • Having 'statusline' call a function to dynamically define what to use in the status line, then have that function look at the g:statusline_winid variable which is set by Vim during the call to that function and query the &filetype for the buffer being edited in that window. (That requires quite a few function calls in Vim to do right. Also, the g:statusline_winid is a fairly addition around the Vim 8.1 timeline, so it might not be available in older versions of Vim, if you care about compatibility.)

There are many more caveats. For instance, the normal setup is for Vim to use different color highlights when a window is in focus (is the one where the cursor is) or not, highlight groups StatusLine and StatusLineNC are used for this purpose. Then there are 9 additional groups User1 through User9 which can be accessed through %1* through %9* settings in the 'statusline' value. Furthermore, highlight settings for these UserN groups also apply on top of StatusLineNC, though only the difference with StatusLine is what applies there.

In short, 'statusline' in Vim is quite complex and it's quite challenging to really get it right. But hopefully this answer will have addressed your question on BufEnter specifically.


I tried echom 'filetype '.&filetype in vimrc and it's empty.

You might need to use autocmd FileType instead which is triggered when the filetype option is set. (h FileType)

You can try something like this to run commands only for vim type files

autocmd FileType vim hi MyStatuslineDevIcon ctermbg=8 cterm=bold ctermfg=3
  • 1
    Welcome to Vi and Vim! This seems more like an idea than a full solution; if you have time to dig deeper, feel free to edit to expand! FWIW, in my vimrc (~/.vim/vimrc), the filetype is correctly set…
    – D. Ben Knoble
    Dec 7 '20 at 16:53
  • Thanks for the suggestion. I've edited my answer to be more like a solution.
    – leaf
    Dec 11 '20 at 7:52

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.