10

After running :bufdo e! All my files lose their filetype setting and I have to manually run :set ft=XXX in each file.

Anyone know how to solve this issue?

Running :bufdo set ft=XXX doesn't work and I don't want to set all files to the same filetype at any rate.

Cheers.

centerback
  • 619
  • 4
  • 16
  • 2
    From the vim docs: _Note: While this command is executing, the Syntax autocommand event is disabled by adding it to 'eventignore'. This considerably speeds up editing each buffer._ – Benj May 09 '12 at 09:47
  • 1
    Actually, I can't reproduce your issue unless I turn automatic filetype detection off, do you have `:filetype on`? – Benj May 09 '12 at 09:56
  • actually, running ':set ft?' on files that have lost their syntax highlighting shows that the filetype is correctly set! Is that what the vim docs are referring to? – centerback May 09 '12 at 10:13
  • 1
    Ok, reproduced it now, running `syntax on` on each buffer restores the highlighting... You might have to write a vim function if you want to do this for all buffers though since `bufdo` won't do it for obvious reasons. – Benj May 09 '12 at 10:17
  • it seems I just have to run `syntax on` on one buffer to restore syntax highlighting on all buffers. Thanks. – centerback May 09 '12 at 10:25
  • Ahh, didn't notice it worked for all buffers (since I was only testing with two :-) – Benj May 09 '12 at 10:27
  • I've added this as an answer for posterity – Benj May 09 '12 at 10:29

3 Answers3

17

The bufdo command doesn't update syntax hightlighting for performance reasons:

From vim docs:

Note: While this command is executing, the Syntax autocommand event is disabled by adding it to 'eventignore'. This considerably speeds up editing each buffer

You can update the syntax highlighting for affected buffers by re-running:

:syntax on

Benj
  • 31,668
  • 17
  • 78
  • 127
7

You can fix this automatically via the following autocmd:

" Enable syntax highlighting when buffers were loaded through :bufdo, which
" disables the Syntax autocmd event to speed up processing.
augroup EnableSyntaxHighlighting
    " Filetype processing does happen, so we can detect a buffer initially
    " loaded during :bufdo through a set filetype, but missing b:current_syntax.
    " Also don't do this when the user explicitly turned off syntax highlighting
    " via :syntax off.
    " Note: Must allow nesting of autocmds so that the :syntax enable triggers
    " the ColorScheme event. Otherwise, some highlighting groups may not be
    " restored properly.
    autocmd! BufWinEnter * nested if exists('syntax_on') && ! exists('b:current_syntax') && ! empty(&l:filetype) | syntax enable | endif

    " The above does not handle reloading via :bufdo edit!, because the
    " b:current_syntax variable is not cleared by that. During the :bufdo,
    " 'eventignore' contains "Syntax", so this can be used to detect this
    " situation when the file is re-read into the buffer. Due to the
    " 'eventignore', an immediate :syntax enable is ignored, but by clearing
    " b:current_syntax, the above handler will do this when the reloaded buffer
    " is displayed in a window again.
    autocmd! BufRead * if exists('syntax_on') && exists('b:current_syntax') && ! empty(&l:filetype) && index(split(&eventignore, ','), 'Syntax') != -1 | unlet! b:current_syntax | endif
augroup END

Edit: Add autocmd nesting for proper restore of highlight groups and handle buffer reloads, as the question explicitly asked for this.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • This seems to only work the first time I run `bufdo e!`. If I run it again, the other files in the buffer lose syntax highlighting. – centerback May 10 '12 at 07:50
  • 1
    @centerback: My main use case was `:bufdo %s... | update`; it seems that buffer reloads must be handled explicitly. I've updated my answer. – Ingo Karkat May 10 '12 at 11:59
  • This restores the default filetype syntax, however it does not restore some customized syntax setting from my vimrc. Is there a "correct" way to set a "highlight GROUP" color in the vimrc so it will be restored? – cmcginty Apr 06 '16 at 01:06
  • Answering my own comment, the solution was to put my `match`, `syntax` and `highlight` commands in an `autocmd` statement so the are reapplied when highlighting is enabled. – cmcginty Apr 06 '16 at 03:35
6

If you're checking for changed files (for example after switching branches in your VCS) then :checktime may be a more appropriate solution than :bufdo e! - it's designed for this purpose and doesn't have the syntax highlighting issue.

Paul Fenney
  • 1,656
  • 1
  • 14
  • 17
  • 1
    This is the correct answer for any time a file (buffer) is modified outside of Vim. Like Paul said, an example would be when switching between branches. – AdamDev Jan 27 '15 at 20:11