3

In general, I have makefiles setup anytime I'm working on C projects. To save and compile these projects, I've bound the ' key to do this:

map ' :wa<CR>:!make<CR>

However, I sometimes open up test files that don't have a makefile, and want to compile those quickly as well:

map ' :wa<CR>:!gcc % -o %< && ./&<<CR>

My question is, how do I create a function to detect if a makefile exists, and then execute the appropriate command? The pseudocode would be the following:

If (makefile exists)
    run make
else
    run gcc on the single file

The only knowledge I have on the vimscript for it would be that I have to bind the ' key to a function. Thanks for any help!

1
  • 1
    Vim's :make command may also be of interest. It calls make by default but can be tweaked to call any command. Nice thing is it captures output and you can jump to errors.
    – Friedrich
    Feb 1 at 8:50

3 Answers 3

6

Wrap it into a function that should be called from your mapping, for instance:

func! MakeOrGcc()
    :write
    " check in the current working directory
    if filereadable('Makefile')
        :!make
    else
        :!gcc % -o %< && ./&<
    endif
endfunc

nnoremap ' :call MakeOrGcc()<CR>
2
  • 1
    Indeed, this way you could even use findfile if you need to search up a hierarchy. I would also mention :make in case the OP is not aware of it.
    – D. Ben Knoble
    Feb 1 at 14:24
  • @D.BenKnoble there was :make before proposed edit which mentioned that OG wanted to use shell's make :)
    – Maxim Kim
    Feb 1 at 22:21
4

Since you're already executing a shell command, you could just use a shell if to test that condition:

map ' :wa<CR>:!if [ -f Makefile ]; then make; else gcc % -o %< && ./&<; fi<CR>
1

Actually, one doesn't need makefiles in order to use make. So it is as simple as

:make all

when you have a "standard" makefile; or

:make foobar

when you've got only foobar.c

1
  • :make %< to make current file
    – Maxim Kim
    Feb 1 at 22:25

Your Answer

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

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