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
    Commented Feb 1, 2023 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
    Commented Feb 1, 2023 at 14:24
  • @D.BenKnoble there was :make before proposed edit which mentioned that OG wanted to use shell's make :)
    – Maxim Kim
    Commented Feb 1, 2023 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
    Commented Feb 1, 2023 at 22:25

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.