2009-04-08 9 views
18

Ce que j'essaie de faire semble être un truc très basique, mais je ne trouve rien à ce sujet. Je travaille sur un projet construit comme d'habitude:Comment "faire" efficacement avec Vim

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

Je voudrais faire mon projet à l'aide de la commande make inclus dans vim. Mais chaque fois que je dois spécifier :make -C ../. Je préférerais, s'il n'y a pas de fichier Makefile dans le répertoire courant, aller dans le répertoire parent. Je le fais déjà avec

set tags+=./tags;/ 

dans mon .vimrc.

En outre, la marque est par défaut moche. Y at-il des options pour ajouter de la couleur à faire, et permettre un accès direct aux erreurs (comme dans Emacs).

Merci

Répondre

7

La solution de rampion est une première étape, mais calculée sur la charge vim. Lorsque je charge une session multi-onglets, le chemin peut être incohérent d'un onglet à l'autre.

Voici ma solution (+ extra avec 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 
1

set makecmd = "make -C .." dans votre .vimrc

+0

Je préférerais, s'il n'y a pas de fichier Makefile dans le répertoire courant, aller dans le répertoire parent. Si Makefile existe, utilisez-le. –

+0

ce n'est pas si facile. définissez votre makecmd comme un script qui teste cette condition ... ce n'est pas si difficile à faire :) –

+0

C'est exactement ce que je demande. Je ne sais pas comment tester si un fichier existe ou pas dans le vimrc –

3

Pour répondre à votre deuxième question, vous pouvez naviguer à travers les erreurs en utilisant la fonctionnalité quickfix dans vim. Quickfix stocke les erreurs dans un tampon et vous permet de naviguer en avant/en arrière à travers eux. Vous devrez peut-être définir la regexp d'erreur pour permettre à VIM de les identifier à partir de la sortie de Make, mais il me semble me rappeler que cela fonctionne plutôt bien (j'ai dû modifier son fonctionnement pour Java Ant construit - ne s'applique évidemment pas ici)

15

Légère modification de what Adam said:

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

sans échappement, c'est

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

qui signifie, pseud o style de code

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

Ceci ne fait qu'un répertoire. Si vous souhaitez une solution plus générale qui ira autant de répertoires que nécessaire, vous devrez être capable de rechercher des répertoires ancêtres jusqu'à ce qu'un Makefile soit trouvé, et je ne suis pas sûr de savoir comment faire cela simplement à partir du ligne de commande. Mais écrire un script (dans la langue que vous préférez) et l'appeler depuis votre makeprg ne devrait pas être difficile.

+15

On peut utiliser une clause 'let' pour éviter un échappement aussi important:': let & makeprg = '[[-f Makefile]] && make || faire -C .. ''. –

+2

'[[a]] && b || c' n'est pas exactement la même chose que 'if a b alors c'. Si 'a' est vrai et' b' renvoie avec un code de sortie non nul, alors 'c' sera aussi exécuté. –

+0

reiner-torenbeek: bon point. Que diriez-vous de [[a]] && (b ; vrai) || c'. – rampion

3

De loin la solution la plus simple est d'avoir un Makefile dans votre répertoire src, qui est la façon dont beaucoup, de nombreux projets sont mis en place quel que soit l'éditeur/IDE. Vous pouvez toujours avoir un Makefile de niveau supérieur qui appelle make -C src, avec les règles pour construire dans src situé dans src où ils appartiennent.

+0

Je ne sais pas pourquoi les projets n'optent pas pour un Makefile de haut niveau autant que possible. –

2

Une autre approche peut être utilisée que si vous avez un seul makefile sur le répertoire racine du projet:

project 
|-- bin 
|-- inc 
|-- src 
| Makefile 

Avec chemin de votre projet dans la variable comme b:projectDir il est possible d'utiliser un « autocommand » pour changer ce répertoire avant commencer à exécuter :make ou :lmake:

augroup changeMakeDir 
    au! 
    autocmd QuickfixCmdPre *make 
       \ if exists("b:projectDir") && 
            \ b:projectDir != expand("%:p:h") | 
        \ exe 'cd ' . b:projectDir | 
       \ endif 
augroup END 

Projectroot plugin peut être utilisé pour définir b:projectDir; il fournit également les commandes pour changer le répertoire courant en répertoire racine du projet:

augroup changeMakeDir 
    au! 
    autocmd QuickfixCmdPre make ProjectRootCD 
augroup END