9

I frequently open whole sets of file at once from inside MacVim. To do this, I typically use the commands:

args *PATTERN*
argdo tabedit

This loads all files in the working directory that match the pattern into the argument list, and then opens them all in separate tabs. Syntax highlighting is not automatically turned on when I do this and I have to set it manually. How can I fix this?

Sean Mackesey
  • 10,701
  • 11
  • 40
  • 66

4 Answers4

8

I had already posted a workaround for :bufdo in a similar question; here is an extended version that handles your use case, too. Working around the automatic setting of 'eventignore' is quite tricky, therefore it's amply commented:

" Enable syntax highlighting when buffers are displayed in a window through
" :argdo and :bufdo, which disable the Syntax autocmd event to speed up
" processing.
augroup EnableSyntaxHighlighting
    " Filetype processing does happen, so we can detect a buffer initially
    " loaded during :argdo / :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.
    " The following autocmd is triggered twice:
    " 1. During the :...do iteration, where it is inactive, because
    " 'eventignore' includes "Syntax". This speeds up the iteration itself.
    " 2. After the iteration, when the user re-enters a buffer / window that was
    " loaded during the iteration. Here is becomes active and enables syntax
    " highlighting. Since that is done buffer after buffer, the delay doesn't
    " matter so much.
    " Note: When the :...do command itself edits the window (e.g. :argdo
    " tabedit), the BufWinEnter event won't fire and enable the syntax when the
    " window is re-visited. We need to hook into WinEnter, too. Note that for
    " :argdo split, each window only gets syntax highlighting as it is entered.
    " Alternatively, we could directly activate the normally effectless :syntax
    " enable through :set eventignore-=Syntax, but that would also cause the
    " slowdown during the iteration Vim wants to avoid.
    " 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,WinEnter * nested if exists('syntax_on') && ! exists('b:current_syntax') && ! empty(&l:filetype) && index(split(&eventignore, ','), 'Syntax') == -1 | 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
Community
  • 1
  • 1
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • 1
    Thanks! This one is the winner because it does exactly what I need. I also appreciate the thorough documentation of how it works. – Sean Mackesey Sep 19 '12 at 19:16
  • Great; glad I could help. Without the thorough documentation, I wouldn't be able to remember and extend it myself. It's always nice to improve one's own configuration based on Stack Overflow questions. – Ingo Karkat Sep 19 '12 at 19:41
6

Something like this should work:

:argdo set eventignore-=Syntax | tabedit

That removes Syntaxfrom the eventignore setting.

Sean Mackesey
  • 10,701
  • 11
  • 40
  • 66
Raimondi
  • 5,163
  • 31
  • 39
  • I already knew that `argdo` removed synatx highlighting but TIL about `eventignore`. Thanks. – romainl Sep 19 '12 at 05:28
  • I like the simplicity. I completely glazed over the simple solution. Thank you for sharing. – Peter Rincker Sep 19 '12 at 14:20
  • This is pretty good but it doesn't turn on syntax for the first item in the arglist. I think that's because set eventignore-=Syntax is not actually run until after that buffer is already opened by the argdo command. Basically this repeats three steps for each arglist item: (1) open next buffer in arglist (in the current window); (2) set eventignore-=Syntax; (3) open a new tab (with a new empty buffer). Then, when the cycle repeats, the next argument in the list is opened in the empty buffer. An unfortunate side effect is you end up with a bunch of empty buffers. – Sean Mackesey Sep 19 '12 at 19:19
2

argdo adds Syntax to the 'eventignore' setting (see :h argdo). This means you do not have any highlighting for those files because the Syntax autocommand event is not fired for that buffer . Which makes it look like the 'filetype' is not being set. This is not true. You can check by doing a :set ft?. You can run :syntax on to turn back on syntax highlighting. But this is not really desirable and feels kludgy.

Probably a better approach is to wean yourself off of using tabs and instead use buffers and the associated buffer commands. Arglist related buffer commands are ::next, :previous, :first, and :last. You can open up specific files with :b file.c or :sb file.c to open the buffer in a new split.

I realize this is a hard pill to swallow and there certainly are times you may really want each buffer in its own tab page. Once you force yourself to use buffers more you will find the need for tabs are rare. You may want to look at Drew Neil's excellent Vimcast on How to use tabs. I also recommend using Tim Pope's unimpaired.vim to move around the argument list easier.

If you really must have each in file in their own tab use :argdo tabe then you should probably follow it with a :syntax on or :tabdo doautocmd Syntax

For more help see:

:h :argdo
:h arglist
:h buffers
:h :b
:h :sb
:h :next
:h :tabdo
:h :doa
:h Syntax
:h :syn-on
Sean Mackesey
  • 10,701
  • 11
  • 40
  • 66
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
  • Thanks for the advice Peter. I do use buffers much of the time, but sometimes tabs are just where its at. It's easier to switch between files than it is with buffers when you have good shortcuts for :tabp and :tabn. Even with something like unimpaired.vim, I find tab switching superior because you have a good visual display of buffer names always on screen. – Sean Mackesey Sep 19 '12 at 03:47
  • If tabs work for you then by all means use them, but I must say when the number of files start to scale up then doing something like `4gt` to get the the proper tab seems to be bit silly. Then you might find yourself doing something like `set swb+=usetab` and start using `:sb file`. Eventually when you get a 100 files it may just seem futile. If you ever find your self here might I suggest forsaking one buffer per tab. Put `set hidden` in your `vimrc` file, learn as many buffer commands as you can, find the joy in splits, lean heavily on ctags/cscope, and use capital letter marks. – Peter Rincker Sep 19 '12 at 14:18
0

I'm not familiar with args or argdo but if you need to open files matching a pattern in different tabs you can use something like:

:next *
:tab ball

:next * opens all files maching the pattern with correct syntax highlighting, however :tab ball opens all files in memory which may be a problem if you have buffers that you don't need to open in tabs.

none
  • 11,793
  • 9
  • 51
  • 87
  • Interesting-- this does open all the files with syntax highlighting, which is what I'd like. But it opens all loaded buffers, which is a pretty big problem. The point of using args and argdo is to specify a set of files to open regardless of what is currently loaded. This is still a decent answer though. I think you should edit it to make clear that this opens them with full syntax highlighting, as that's what the question is about. – Sean Mackesey Sep 19 '12 at 03:42