vimmakefilevim-quickfix

Vim: Avoid having to press ENTER after successful make?


$ ls
Makefile          html-page/        page-generator.m4
Run               includes/

Alongside the Makefile, I have a script Run that is executed only when make completes without errors. This I've managed to implement with the following in my .vimrc file, which also looks for the Makefile in parent directories if needed.

" Before the 'make' quickfix command, run my quickfix pre-commands
autocmd QuickfixCmdPre make call MyQuickfixCmdPre()

" After the 'make' quickfix command, run my quickfix post-commands
autocmd QuickfixCmdPost make call MyQuickfixCmdPost()

and

function! MyQuickfixCmdPre()
    " Save current buffer, but only if it's been modified
    update

    " (h)ead of (p)ath of % (current buffer), i.e. path of current file
    let l:dir = expand('%:p:h')

    " Remove final / and smack a /Makefile on the end, glob gives empty if file doesn't exist
    while empty(glob(substitute(l:dir, '/$', '', '') . '/Makefile'))
        " There's no Makefile here. Are we at the root dir?
        if l:dir ==# "/"
            " Just use dir of current file then
            let l:dir = '.'
            break
        else
            " Try the parent dir. Get (h)ead of dir, i.e. remove rightmost dir name from it
            let l:dir = fnamemodify(l:dir, ':h')
        endif
    endwhile
    " Makefile is in this dir, so local-cd (only this window) to the dir
    execute "lcd " . l:dir
endfunction

function! MyQuickfixCmdPost()
    " Get number of valid quickfix entries, i.e. number of errors reported,
    " using filter to check the 'valid' flag
    let l:err_count = len(filter(getqflist(), 'v:val.valid'))

    if l:err_count ==# 0
        " The make succeeded. Execute the Run script expected in the same dir as Makefile
        call system('./Run')
        redraw!
    endif
endfunction

With this in place, after typing :mak in vim, the code is made and run... There are two possible results:

  1. If there are errors during make, vim will present these errors with a Press ENTER or type command to continue afterwards, which is all good.
  2. If make succeeds without errors, however, my Run script is executed, for testing my code (in this case an html file shown in a browser), but then when I switch back to vim, I have to press enter to get rid of a message from vim that I don't need to read because it doesn't tell me about errors. This message used to look like this:
"includes/m4includes/subs.m4" 34L, 759B written
:!make  2>&1| tee /var/folders/zk/0bsgbxne3pe5c86jsbgdt27f3333yd/T/vkbxFyd/255
m4 -I includes/m4includes page-generator.m4 >html-page/mypage.html
(1 of 1): m4 -I includes/m4includes page-generator.m4 >html-page/mypage.html
Press ENTER or type command to continue

but after introducing the redraw! in MyQuickfixCmdPost() is now reduced to:

(1 of 1): m4 -I includes/m4includes page-generator.m4 >html-page/mypage.html
Press ENTER or type command to continue

yet still with the need to press enter.

How do we avoid having to press enter every single time we return to vim after a successful compilation? Any ideas?

Note: vim has a -silent command-line option, but as far as I can see this would silence all the Press ENTERs, and the goal here is to only avoid them after a successful make.


Solution

  • Just add call feedkeys("\<CR>") afterwards. There are not many places you need feedkeys() (often normal! or similar commands will do), and there are subtle effects (look at the flags it takes carefully). Fortunately this is one place it is useful.