Search code examples
vimmakefilegrepvi

Colorizing the output of :make, :grep, etc., in Vim


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.


Solution

  • 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.)