3

What exactly is Vim doing when executing the :make command?

I was expecting that it just executes the content of the makeprg variable just like running :!make and additionally collects the output, but apparently the behavior is different. For example the terminal size is set up differently.

For example create a makefile with the following content

check:
    echo asdf > foo.txt
    aspell -c foo.txt

Then compare the behavior of :make and :!make.

Is it different for you, too, or is this something strange with my setup?

1 Answer 1

5

From :h :make:

The ":make" command executes the command given with the 'makeprg' option.
This is done by passing the command to the shell given with the 'shell'
option.  This works almost like typing
        ":!{makeprg} [arguments] {shellpipe} {errorfile}".

{makeprg} is the string given with the 'makeprg' option.  Any command can be
used, not just "make".  …

[arguments] is anything that is typed after ":make".
{shellpipe} is the 'shellpipe' option.
{errorfile} is the 'makeef' option, with ## replaced to make it unique.

So, it's not exactly the same as just :!make. Following through, for shellpipe:

                                                'shellpipe' 'sp'
'shellpipe' 'sp'        string  (default ">", "| tee", "|& tee" or "2>&1| tee")
        …
        For Unix the default it "| tee".  The stdout of the compiler is saved
        in a file and echoed to the screen.  If the 'shell' option is "csh" or
        "tcsh" after initializations, the default becomes "|& tee".  If the
        'shell' option is "sh", "ksh", "mksh", "pdksh", "zsh" or "bash" the
        default becomes "2>&1| tee".

So, the actual command is more like:

:!make 2>&1 | tee bar

And, in fact, if you run:

aspell -c foo.txt 2>&1 | tee bar

You'll get the same behaviour.

So, this is perfectly normal behaviour.

3
  • 1
    nice reference, that trilogy of five books is awesome :)
    – mMontu
    Commented Feb 25, 2016 at 11:21
  • 1
    That explains the difference between :make and :!make, thanks! With that explanation it was easy to prepend aspell with screen so this behaviour can be avoided since I do not want to include the aspell output in the errorfile anyway. Anyhow it would be interesting why "|& tee" modifies the terminal width (and "| tee" not, by the way...).
    – koalo
    Commented Feb 25, 2016 at 12:47
  • 1
    @koalo aspell might be testing if either of stderr or stdin is connected to a TTY and using to get the display size, etc. (aspell -c foo 2>bar works fine too). That would be a question for Unix & Linux, however :)
    – muru
    Commented Feb 25, 2016 at 12:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.