views:

548

answers:

5

Hi,

what I am triing to do seems a very basic stuff, but I can't find anything about it. I am working on a project built as usual:

project
|-- bin
|-- inc
`-- src

I would like to make my project using the make command included in Vim. But each time I have to specify :make -C ../. I would prefer, if there is not Makefile file in the current directory, go in the parent directory. I already do that with

set tags+=./tags;/

in my .vimrc

Furthermore, the make is by default ugly. Are there options to add color to make, and allow a direct access to the errors (as in emacs).

Thanks

+1  A: 

set makecmd="make -C .." in your .vimrc

Adam Hawes
I would prefer, if there is not Makefile file in the current directory, go in the parent directory. If Makefile exists, use it.
Jérôme
that's not so easy. set your makecmd to be a script that tests that condition... it's not all that hard to do :)
Adam Hawes
That is exactly what I am asking. I don't know how to test if a file exists or not in the vimrc
Jérôme
+2  A: 

To answer your second question, you can navigate through the errors using the quickfix functionality in VIM. Quickfix stores the errors in a buffer and allows you to navigate forward/backwards through them.

You may have to define the error regexp to allow VIM to identify these from Make's output, but I seem to remember that it works out-of-the-box rather well (I've had to modify how it works for Java Ant builds - obviously doesn't apply here)

Brian Agnew
+2  A: 

Slight modification of what Adam said:

 :set makeprg=[[\ -f\ Makefile\ ]]\ &&\ make\ \\\|\\\|\ make\ -C\ ..

Unescaped, this is

 [[ -f Makefile ]] && make || make -C ..

which means, pseudo code style

 if file-exists(Makefile) 
 then make
 else make -C ..

This only goes one directory up. If you'd like a more general solution that will go as many directories up as necessary, you'll need to be able to search ancestor directories until a Makefile is found, and I'm not sure how to do that simply from the command line. But writing a script (in whatever language you prefer) and then calling it from your makeprg shouldn't be hard.

rampion
A: 

The solution of rampion is a first step, but computed on vim load. When I load a multi tab session, the path can be inconsistent from one tab to another.

Here my solution (+ extra with tabnew).

fun! SetMkfile()
  let filemk = "Makefile"
  let pathmk = "./"
  let depth = 1
  while depth < 4
    if filereadable(pathmk . filemk)
      return pathmk
    endif
    let depth += 1
    let pathmk = "../" . pathmk
  endwhile
  return "."
endf

command! -nargs=* Make tabnew | let $mkpath = SetMkfile() | make <args> -C $mkpath | cwindow 10
Jérôme
+1  A: 

By far the easiest solution is to have a Makefile in your src directory, which is the way that many, many projects are set up regardless of editor/IDE. You can still have a top-level Makefile that calls make -C src, with the rules for building in src located in src where they belong.

dwc