13

I have an autocommand defined in my vimrc:

au BufWritePost * !./make.sh

The script make.sh compiles a .tex file 3 times and I don't want the output to be displayed.

Is there a way to suppress the output?

I tried to add silent one line before the au command, but it didn't work. I also tried this way with no success.

20

Silent should go before !./make.sh, not before au. Putting silent before au just means it will register the autocommand silently. It should look like this instead:

au BufWritePost * silent! !./make.sh

One issue with running an external command like this with the :silent command is that the screen does not redraw, leaving you with a blank screen. However, vim does have a command which redraws the screen, which can be used like so:

au BufWritePost * silent! execute "!./make.sh >/dev/null 2>&1" | redraw!

The reason I need to use the execute command is because the :! command uses any characters found after it, which means I couldn't just do silent! !./make.sh | redraw! because bash would try to interpret all of the characters after !.

Notes

Note that :silent! ignores error messages, whereas :silent doesn't. Also, the >/dev/null 2>&1 part redirects all output of !./make.sh to /dev/null. You can read more about i/o redirection in bash here.

Relevant Help Topics

  • :help :execute
  • :help :silent
  • :help :!
  • :help :bar
  • The second command worked, although it still prints output on the screen. Additionally, I don't need to press Enter when the script ends anymore, which is good. But I wonder if there is any way to totally suppress the output. – Andre Herman Bezerra Apr 24 '15 at 19:44
  • 1
    Does replacing execute "!./make.sh" with execute "!./make.sh >/dev/null 2>&1" help? This redirects all output of the command to /dev/null. Read tldp.org/LDP/abs/html/io-redirection.html for more information on redirection in bash. – EvergreenTree Apr 24 '15 at 19:56
  • I should have thought of that! It works. Thanks! – Andre Herman Bezerra Apr 24 '15 at 19:59
7

The answer to your direct question is just as @EvergreenTree posted. However I feel like you are missing some of Vim builtin tool for building/compiling/linting projects. Most notably :make and the quickfix list.

What does using :make get us?

Using :make allows for you to collect your errors up into a list known as the quickfix list. Using the quickfix you can navigate between the errors in your files, so you are jumping right to where the compiler says the error is (handy right?).

:make

Running :make will execute the make program, 'makeprg'. Then parse the output with 'errorformat' and put each entry into the quickfix list.

Typically 'makeprg' defaults to the make command which runs a Makefile. However you can change your 'makeprg' via the :compiler command or set it directly.

You can also pass extra arguments to :make. e.g. :make clean

Note: running :make will often show the output of the command at the bottom of the screen with a prompt asking to press enter. Just press enter as all the output will be available in the quickfix list. You can suppress this via :silent, e.g. :silent make.

A common custom command for a silent make is:

command -nargs=* -bar Smake silent make <args> <bar> cwindow

quickfix list

After you run :make your quickfix list will hold the output of compiler.

Use the following command to navigate the quickfix list.

  • :copen to open the quickfix window
  • :cclose to close the quickfix window
  • :cnext/:cprev to move to the next/previous item
  • :cc to print out at the bottom the current error or :cc 3 to show a specific error in this example 3

Personally I use Tim Pope's unimpaired plugin to navigate the quickfix list.

What about running :make automatically and silently?

You can do this with an :autocmd just like you where.

augroup auto_make
    autocmd!
    autocmd BufWritePost * silent make
    autocmd QuickFixCmdPost *make* cwindow
augroup END

As a bonus I added in opening the quickfix window via :cwindow if there are any errors present.

Note: Should be more specific with that file pattern on the BufWritePost autocmd so that un-related files don't build.

There even more?!

This is using just a few of Vim's builtin command plus a few autocmd's for convince. There are of course plugins and tools that might aid you

  • Dispatch.vim can be used to run :make jobs asynchronously.
  • Syntastic plugin syntax checks file after :write.
  • Ale.vim (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim and Vim 8 while you edit your text files.
  • Unimpaired.vim makes managing the quickfix list easy.
  • Plain old Makefiles. Unless your ./script.sh is very complicated you may want to look into using make. It can scale do more tasks later and is a common building tool.
  • You can use Vim Awesome to search for more plugins that might help.

Conclusion

Personally I integrate :make and the quickfix into my own workflow. I believe capturing the output of your build process and capturing the errors to be well worth the investment. As an added bonus you will possibly become more comfortable with the quickfix list and can use the list for other applications like :grep.

For more help see:

:h :make
:h quickfix
:h 'makeprg'
:h 'errorformat'
:h :compiler
:h :copen
:h :cwindow
:h :cnext
:h :cc
  • I thought about :make while I was answering this, but I didn't include it. It is a better idea to use make fore compiling things. – EvergreenTree Apr 25 '15 at 0:21
  • how to change the autocmd to only run makeprg on a certain file. – Ibn Saeed May 18 '17 at 4:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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