L'autocomplétion C/C++ sous vim

mamiemando Messages postés 33432 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 décembre 2024 - Modifié le 30 mai 2022 à 04:31

Auto-complétion sous ViM


Ce tutoriel s'adresse aux personnes qui utilisent Vim sous windows ou Linux. Ici, je vais plutôt orienter le tutoriel pour les personnes sous Linux.

Introduction

L'auto-complétion est quelque chose de bien connu sous linux puisqu'on l'utilise régulièrement, typiquement dans une console. Toutefois, la seule auto-complétion que propose Vim ne tient pas compte de la sémantique du langage dans lequel on code.

Auto-complétion native : Quand on appuie sur Ctrl N (ou Ctrl P) lorsqu'on est en train de taper un mot, Vim cherche dans le fichier un mot qui commence par les mêmes lettres. Malheureusement, le mot proposé n'a pas forcément de sens, car une telle auto-complétion ne tient pas compte de ce que symbolise le mot. Ainsi Vim sera par exemple amené à proposer un "mot" qui correspond à un type là ou une méthode est attendue.
class plop(){
  protected:
   int plopons;
  public:
   plop(){}
   void plopez(){}
};

int main(){
  plop p;
  p. // <-- Ctrl P à cet endoit propose successivement : plopez, plop... alors que c'est forcément plopons</bold>
  return 0;
}


Auto-complétion sémantique : Pour que la logique du code soit pris en compte, il faut utiliser un plugin
vim
basé sur
ctags
.Lorsque
ctags
examine une arborescence de fichiers source, celui-ci crée un fichier (appelé tags) qui référence chacun des symboles qui y figurent.

Installation

1) Installer
ctags
.

Exemple : sous Debian ou les distributions qui en dérivent :
sudo apt update
sudo apt install exuberant-ctags


2) Récupérer le plugin Vim d'auto-complétion et mettre tout ce qui concerne l'auto-complétion dans
~/.vim
:

mkdir -p ~/.vim/tags
mv omnicpp*zip ~/.vim
cd ~/.vim
unzip omnicpp*zip
cd -


3)
ctags
est capable d'examiner sans problème les headers des librairies Qt, OpenGL, SDL. Toutefois pour la STL, il faut récupérer des headers "simplifiés". Décompresser cette archive et on crée les tags de la STL :
tar xjvf cpp_src.tar.bz2
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ cpp_src && mv tags ~/.vim/tags/stl


4) Générer les tags pour les librairies installées (à adapter si les librairies sont installées ailleurs). Par exemple pour les librairies OpenGL, SDL et Qt, il suffit de taper les trois commandes suivantes :
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/GL/  && mv tags ~/.vim/tags/gl
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/SDL/ && mv tags ~/.vim/tags/sdl
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/qt4/ && mv tags ~/.vim/tags/qt4

Configuration

À présent, il faut dire à
vim
de charger le plugin et les différents fichiers de tags. Pour cela, il suffit de rajouter à la fin du fichier
~/.vimrc
les lignes suivantes :

" prérequis tags
set nocp
filetype plugin on

" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/tags/stl
set tags+=~/.vim/tags/gl
set tags+=~/.vim/tags/sdl
set tags+=~/.vim/tags/qt4

" build tags of your own project with CTRL+F12
"map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
noremap <F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>
inoremap <F12> <Esc>:!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<cr>

" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_MayCompleteDot = 1
let OmniCpp_MayCompleteArrow = 1
let OmniCpp_MayCompleteScope = 1
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]

" automatically open and close the popup menu / preview window
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview


Si seuls certains fichiers tags ont été générés, commenter les autres en rajoutant le caractère " en début de ligne. Par exemple, si on n'a pas généré
~/.vim/tags/gl
et
~/.vim/tags/sdl
:
set tags+=~/.vim/tags/stl
"set tags+=~/.vim/tags/gl
"set tags+=~/.vim/tags/sdl
set tags+=~/.vim/tags/qt4

Il ne reste plus qu'à sauver ce fichier et (re)lancer vim afin que celui-ci tienne compte des modifications apportées à
~/.vimrc
.

Utilisation

Tout ce qui a été taggué au préalable (c'est-à-dire dans ce tutoriel les tags de la STL, de QTt de SDL, et d'OpenGL) est déjà accessible dans l'auto complétion. Il suffit d'appuyer sur ctrl+P ou ctrl+N. Une fois que la liste apparaît, on peut utiliser les flèches pour mettre en surbrillance la bonne proposition et appuyer sur entrée.

Toutefois, ce n'est pas complètement terminé. Il faut (re)générer les tags des symboles (variables, fonctions, types...) spécifiques au projet que l'on développe. Pour cela, il faudra encore une fois générer un fichier de tags. Et bien entendu, il faudra rafraîchir ce fichier à chaque fois que l'on ajoutera, supprimera, ou modifiera un symbole du projet afin que celui-ci soit à jour.

Comme c'est assez fréquent, il est recommandé de mapper une touche du clavier pour déclencher une passe de ctags. Dans l'exemple de fichier
~/.vimrc
précédent, ceci est assuré par la touche F12.

Liens