Développer avec symfony sous Vim avec Project et ctags

Publié le par greg

Bon, je vous vois déjà en train de me lancer des cyber cailloux en criant à l'arnaque du post de blog réchauffé. C'est vrai, je vous faisais déjà part de ma découverte du plugin Project dans cet article. Mais après plusieurs mois d'utilisation intensive, ce plugin de Vim a définitivement changé ma façon de travailler en accroissant (encore) la rapidité du développement, c'est ce retour d'expérience que je me propose de partager avec vous aujourd'hui.

Allez, pour ne pas prendre l'habitde de soliloquer je vous propose de m'accompagner au fure et à mesure des manips que je présenterai ici, il n'est même pas besoin de bien connaître Vim pour ce faire.

Qu'est ce que Project ?
Project est un plugin de Vim écrit par Aric Blumer qui permet d'afficher un navigateur de projet à gauche de l'écran d'édition. Pour installer ce plugin dans Vim, il est nécessaire de télécharger l'archive présente sur cette page et de la placer soit dans /usr/share/vim/vimcurrent/plugin (debian) pour permettre à tous les utilisateurs d'y avoir accès soit simplement dans votre $HOME/.vim/plugin.
Une fois ce plugin installé, vous pouvez lancer Vim avec Project en tapant vim +Project ou pour les utilisateurs de screen : screen vim +Project . Vous pouvez bien sûr lancer Project à n'importe quel moment quand vous êtes sous Vim en tapant :Project
Une fois cela fait, vous devriez obtenir quelque chose comme ça :


Un peu vide me direz vous, c'est normal vous n'avez pas ouvert de fichier et votre liste de projets est vide. Cette barre sur la gauche est le navigateur de projets. L'astuce est tellement simple qu'elle en est diablement efficace : ce gestionnaire de projets n'est ni plus ni moins qu'un bête fichier texte (le plus souvent $HOME/.vimprojects) auquel le plugin donne quelques propriétés intéressantes.

Si vous avez un projet symfony à portée de Vim alors ne reste plus qu'à créer une entrée dans votre gestionnaire de projet à l'aide de la combinaison «\C» (create, les majuscules indiquent un comportement récursif). Le plugin vous demande alors
(1) Enter the Name of the Entry:
l
e nom de l'entrée, nous allons ici lui donner le nom du projet tel que nous voulons le voir apparaître dans la fenêtre. (par exemple : «mon projet de test»)
(2) Enter the Absolute Directory to Load:
le chemin absolu du répertoire à charger. Indiquer ici le chemin absolu du répertoire racine du projet symfony. Si vous avez déjà un terminal ouvert dans ce répertoire, la commande «pwd» devrait vous préparer le copier-coller.
(3) Enter the CD parameter:
Ce paramètre permet à Project de changer le répertoire courant de Vim. Nous verrons plus loin que cela nous ouvre des horizons insoupçonnés. Dans le cadre d'un projet symfony, mettez là encore le chemin absolu du répertoire racine de votre projet.
(4) Enter the File Filter:
Rentrez ici une liste séparée par des espaces du masque de sélection de fichiers que vous voulez voir apparaître dans votre projet, par exemple, dans le cas d'un projet symfony  : *.php *.yml *.sql *.ini *.txt *.css *.js .

Crrr crrr, le disque se met à tourner, si vous avez la lib symfony dans votre projet, cela va mettre quelques secondes à tout importer, une fois le travail fait, vous voila avec toute l'arborescence dépliée de votre projet. Un coup de barre espace et vous agrandissez votre vue du projet (un coup de barre espace et l'espace se réduit). Placez votre curser sur une entrée quelconque du projet et appuyez successivement sur «zm», cette commande permet de réduire tous les folds, nous ne voyez plus que l'entrée principale de votre projet. Placez votre curser dessus et appuyez sur «enter», l'entrée se déplie et cela vous rappelle quelque chose n'est ce pas ?


La première chose que nous pouvons faire est d'enlever les entrées «cache» et «log». Pour, cela, il suffit tout simplement de placer le curser sur la ligne correspondante et de faire «dd». C'est là qu'est la grande force de Project, cette vue n'est qu'un bête fichier texte entouré de scripts simples. Vous pouvez faire des modifs dessus, replacer des entréer dans l'ordre que vous voulez puis «:w» pour enregistrer notre projet dans $HOME/.vimprojects.

Plaçons maintenant le curser sur l'entrée «apps» et validons. L'entrée se déplie, nous devrions avoir quelque chose comme ça :

Comme vous le voyez, les questions que Project vous a posé tout à l'heure sont des attributs de l'entrée principale. Vous pouvez évidemment les mofier directement, une fois votre modif terminée, en mode commande, faite un «\R» (refresh) et elle devrait être prise en compte. Ce qui est important ici, est de voir que l'entrée «apps» ne possède pas tous les attributs de son père, il n'en possède qu'un : le nom du sous répertoire. C'est grâce à la notion d'héritage que l'entrée «apps» possède automatiquement le bon filtre de fichiers. Vous pouvez redéfinir le filtre pour certaines des entrées de votre projet («config» par exemple).

La navigation : utilisation courante de Project
La navigation dans project est très simple, les touches de mouvement (flèches, recherche, sauts) sont évidemment accessibles (les marqueurs aussi...) pour aller d'une entrée à l'autre, les folds sont des replis de Vim comme les autres à part que l'appuie sur la touche «enter» vous permet de les déplier, replier, l'appuie sur la touche «enter» sur un fichier l'ouvre dans votre fenêtre de droite et place le curser dans la fenêtre du fichier.

 La combinaison «ctrl w» et flèche vous permet de sauter d'une fenêtre à l'autre (en général «ctrl w» préfixe les opérations sur les fenêtres (window)). Cela ouvre toute la puissance du split de Vim. Faites un «:sp» et Vim ouvre un split horizontal, «ctrl w» «flèche gauche» vous permet de retourner dans la vue Project, sélectionnez un nouveau fichier et le voila qui s'ouvre dans votre split. Vous pouvez ainsi par exemple avoir sous les yeux directement le contrôleur et la vue pour vous assurer du passage de paramètres ....


Pour ceux qui veulent en savoir plus sur le déplacement dans Vim, je vous conseille la méthode hypoallergénique.

Comment Vim se transforme en éditeur tout en un
L'astuce ici est que dès que vous travaillez sur une entrée de votre projet, le paramètre CD de project rentre en action et place votre Vim dans le répertoire racine de votre projet. Il devient ainsi possible d'utiliser directement l'utilitaire «symfony» depuis Vim !
:!./symfony cc
et le tour est joué ! Je nous vous parle pas des commandes svn... Pour bien faire, il suffit de mapper les opérations les plus courantes sur les touches f2 à f12 (f1étant réservé pour l'aide de Vim), je vous ai concocté un petit extrait à mettre dans votre .vimrc
map <F2> :!phptags ^M:set tags=.ctags^M
map <F5> :!svn up^M
map <F6> :!svn ci^M
map <F7> :!svn
map <F9> :!./symfony cc^M
map <F10> :!./symfony propel:build-model^M
map <F11> :!./symfony propel:build-all-load
map <F12> :!./symfony


Pour faire le ^M (retour chariot), il suffit de faire «ctrl v»«ctrl m». (utile aussi dans des chercher/remplacer).

On s'habitue très vite au F9 pour clearer le cache, notez les options qui ne font pas de retour chariot pour attendre des informations supplémentaires de votre part (F7, F11 et F12). La touche F2 sera décrite plus loin dans cet article.

Commandes de groupe

Il est également possible de définit des actions à effectuer sur des parties ou une entrée d'un projet, par exemple le «svn revert» qui permet d'annuler les dernières modifs sur un fichier et revenir à l'état précédent.

Pour cela, il suffit d'entrer en mode commande la ligne suivante :
:let g:proj_run1='!svn revert %f'
Cela vous permet alors en vous plaçant sur un fichier de votre projet et en tapant «\1» de lancer «svn revert» sur ce fichier. Vous pouvez ainsi définir 9 fonctions Vim à affecter aux combinaisons de «\1» à «\9».

Pour définir des commandes Vim s'appliquant à tous les fichiers d'une sous arborescence, il suffit de déclarer les variables de «g:proj_run_fold1» à «g:proj_run_fold9» (amateurs de la commande dos2unix, vous voila comblés). Il suffit ensuite de faire «\f1» pour appliquer la commande 1 au niveau courant et «\F1» pour inclure tous les enfants.

Cerise sur le gateau : la commande grep
Grep existe depuis Unix. Cette commande est tellement indispensable au programmeur qu'un bon système ne peut se passer d'un bon grep. Ici nous sommes doublement servis :
- le grep ne s'applique qu'aux entrées dans Project: aux entrées qui nous intéressent ! (finis les entrées .svn et cache etc))
- le grep est intégré à Vim, la liste des résultats permet d'ouvrir directement le bon fichier au bon endroit.

Pour lancer grep, dans la fenêtre Project un «\g» ou «\G» (récursif) sur l'entrée voulue vous ouvre le dialogue suivant :
GREP options and pattern: -iHn *motif*
Vous pouvez évidemment utiliser autre chose que -iHn pour les options... Il n'est pas impossible que les codes couleurs de Vim cassent un peu la mise en page de votre terminal. Un «ctrl l» (L) rafraichira votre terminal. Vous devriez voir ceci :

Une liste de fichiers avec la ligne correspondante à votre recherche. Vous pouvez vous déplacer avec les flèches et appuyez sur «enter» pour choisir le fichier à ouvrir, il s'ouvrira et placera le curser à la bonne ligne. un «:q» dans la fenêtre du grep pour finir.

Les plus curieux d'entre vous n'hésiteront évidemment pas à aller voir la page d'aide de project :
:help project

Naviguer dans les classes avec exubertant-ctags:
L'utilitaire ctags permet de naviguer rapidement dans les dépendances de classe d'un projet. Pour cela, dans un shell à la racine de votre projet symfony, la commande suivante (volée et adaptée de ce très bon blog):

ctags -f .ctags -h ".php" -R \
--exclude="\.svn" \
--exclude="/cache" \
--exclude="/log" \
--totals=yes \
--tag-relative=yes \
--PHP-kinds=+cf \
--regex-PHP='/abstract class ([^ ]*)/\1/c/' \
--regex-PHP='/interface ([^ ]*)/\1/c/' \
--regex-PHP='/(public |static |abstract |protected |private )+function ([^ (]*)/\2/f/'


crééra un fichier «.ctags» dans le répertoire courant. Je vous conseille d'enregistrer la commande dans un script shell (qui s'appellerait par exemple phptags). Cela tombe bien, c'est justemment le même nom de fichier que celui du fichier pointée par la commande mappée en <F2> plus haut dans Vim. Une fois les tags avalés dans Vim, placez vous sur une classe (par exemple sfActions) et un «ctrl ]» vous permettra d'ouvrir le fichier déclarant la classe sfActions,«ctrl t» reviendra au fichier précédent.
Pour lister les méthodes de la classe courante, rien de plus facile «:g:function:#» vous donnera la liste des méthodes et le numéro des lignes ... que demander de plus ?

Publié dans vim

Commenter cet article

ioo 22/09/2008 11:53

Bonjour,Merci pour le "zm", c'est violent mais moins que fermer project et le relancer dans vim ;-)++

ioo 15/09/2008 14:28

Bonjour Grégoire,Merci pour l'article... je suis passé sous vim dès ton premier :-)Puisque tu as l'air sous debian, lorsque tu refreshs un projet est-ce que cela fonctionne, par exemple lorsque tu crées un module.Perso je suis obligé de le saisir à la main pour ce qui est dossier.Ensuite je dois refresh à nouveau 1 à 1 les dossiers pour voir les fichiers. Cela a aussi l'effet désagréable de me deployer toute l'arbo de tous les projets...Une idée ?

greg 15/09/2008 21:45


Bonjour,
Le refresh ne fait que rafraichir les listes de fichiers et ne rajoute pas de répertoire. Pour ajouter des modules, je passe par un \\C. Pour rajouter des nouveaux fichiers, je crée directement
l'entrée dans project et ensuite j'appuie sur entrée.
Effectivement, le fait de faire \\C déploie toute l'arbo, un coup de «zm» est un peu violent mais résoud le problème. Du coup, ça vaut le coup de déplacer les parties les plus utilisées de l'arbo
de façon a les atteindre en moins de coups possibles.