28

When building my application using the :make command in Vim, the output is not colorized. I have configured the makefile to use clang as the C compiler, and when running make outside of Vim or when running :!make, clang's output is colorized. :set makeprg returns makeprg=make, just for reference.

I have the same issue with grep: when running :grep, the output is not colorized; when running :!grep, it is. I have tried using the --color option with :grep, to no avail. :set grepprg returns grepprg=grep -n $* /dev/null.

I've read through VIM Unix commands printed in color and also How to color my vimgrep result patterns. The former seems to have the opposite problem (i.e. :!command output not colorized); the latter doesn't have any alternative to dropping down to the shell, which I don't feel is a "correct" fix for the issue.

Community
  • 1
  • 1
welp
  • 653
  • 7
  • 11
  • Adding `--color` to `grepprg` breaks `:grep`, here, I'm not sure how to include it in the arguments safely. In CLI Vim, both `:!grep foo *` and `:grep foo *` "drop down to the shell". What didyou try for `:make`? – romainl Oct 07 '12 at 07:12
  • Did `:!grep foo *` have colorized output? There are no options for colorizing `clang` output as far as I can see, I was planning on doing some tests by setting colorgcc as my `makeprg` later today, so I will add a comment with the results of that. I did try setting `makeprg` to `echo\ -e\ \"\\033[32m\ Hello\ World\"` to see if it would be colorized, and it /was/, which was interesting. – welp Oct 07 '12 at 19:05

2 Answers2

25

The problem is that when Vim runs other commands via :make or :grep, those commands don't get a terminal for their standard output -- in the sense that for them isatty(STDOUT_FILENO) is false -- because Vim is capturing the output on its way to being displayed on the terminal. On the other hand, when you use :!make or :!grep, standard output is just going to the terminal.

Clang by default and grep --color=auto (which is probably how you have it aliased) use the terminalness of stdout to decide whether to colourise their output. This is convenient in that you get colourful output on your terminal but capture just the text when you redirect output to a file -- all without needing to add extra command line options.

So what you want to do is override these commands' usual smarts so that they always colourise their output.

For grep, you can use --color=always when it is run via :grep within Vim:

:set grepprg=grep\ --color=always\ -n\ $*\ /dev/null

and depending on your colour settings and version of grep this will work well enough.

For clang, you can change your Makefile to use clang -fcolor-diagnostics so as to force colourisation or more flexibly add an extra variable to $(CC) that will be overridden when run via :make within Vim:

:set makeprg=make\ EXTRA_CFLAGS=-fcolor-diagnostic

However (at least with clang 3.0 and vim 7.3) you will find that clang's style of colourisation prevents Vim from picking out filenames and line numbers from the diagnostics, so doing this wrecks the advantage of using :make rather than :!make.

You may be able to teach Vim to pick out the filenames etc from the surrounding ANSI escape sequences that do the colourisation by adding more entries to Vim's errorformat option to match the colourised clang-style diagnostics. (And similarly with grepformat if your grep colourisation colours the filenames or linenumbers.)

John Marshall
  • 6,815
  • 1
  • 28
  • 38
  • 1
    Thanks, this is pretty much perfect! I saw this initially before your edit, and thought of the same thing as you. I'm going to see if I can come up with a working `errorformat` option, and see if I can add it to this answer as it may help others. – welp Oct 07 '12 at 21:19
  • 1
    @welp, if you use `:cw`, then vim does its own colorization of the results in the Quickfix window. Is this sufficient, or maybe I've missed something – Aaron McDaid Jul 12 '15 at 15:14
0

When you run :grep or :make (as opposed to :!grep or :!make), the output is not only shown in the terminal, but also sent to the quick-fix window, from which it is processed. You can access the quick fix windo using the vim-command :copen. The quick fix window is essentially a text file that is opened in read-only mode. Like in any other text file, colors are not supported in the quick fix file. Instead, they are represented with escape characters like [01;34m. Therefore, producing colorized output from make (or grep) will mess up the output as it is shown in the quick-fix window, even if you can get vim to process it, and send the cursor to the selected error/warning/find message.

The question whether the output is colorized now becomes a little subtle: I suggest that the terminal output should remain uncolored, but that the quick-fix output should be colorized. The color scheme in the quick fix window is not defined by any color-indications in the file itself, but in the syntax highlighting of the quick fix window, defined in the file qf.vim (/usr/share/vim/vim81/syntax/qf.vim on my computer). The color scheme defined in qf.vim does not add much color to the quick fix window, but the syntax hightlighting scheme may be extended by creating the file ~/.vim/syntax/after/qf.vim. I use cmake in combination with the gnu and/or the intel compilers, and get nice-looking results with the following contents for ~/.vim/syntax/after/qf.vim:

syn match qBuilt            "Built target *" nextgroup=qTarget
syn match qTarget           ".*$"   contained

syn match qEnteringLeaving  ": \(Entering\|Leaving\) directory *" nextgroup=qdSeparator
syn match qdSeparator       "'"     nextgroup=qdName contained
syn match qdName            "[^']*" contained

syn match qbProgress        "\[ *[0-9]*%\]"
syn match qBuild            "Building .* object"
syn match qWarn             "warning\( *#[0-9]*\|\):"
syn match qError            "error\( *#[0-9]*\|\):"
syn match qRemark           "remark\( *#[0-9]*\|\):"

hi def link qTarget          Constant
hi def link qError           Error
hi def link qWarn            Error
hi def link qRemark          WarningMsg
hi def link qEnteringLeaving Keyword
hi def link qBuild           Keyword
hi def link qBuilt           Keyword
hi def link qdName           Include
hi def link qbProgress       Special
Nathan
  • 3,558
  • 1
  • 18
  • 38