Comment appeler clang-format sur un dossier de projet cpp?


87

Existe-t-il un moyen d'appeler quelque chose comme clang-format --style=Webkitpour un dossier de projet cpp entier, plutôt que de l'exécuter séparément pour chaque fichier?

J'utilise clang-format.pyet vimpour le faire, mais je suppose qu'il existe un moyen de l'appliquer une fois.

Réponses:


46

Qu'en est-il de:

clang-format -i -style=WebKit *.cpp *.h

dans le dossier du projet. L'option -i le rend inplace (par défaut, la sortie formatée est écrite dans stdout).


1
ou si vous utilisez un fichier de configuration et que vous souhaitez formater plusieurs types de fichiers: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos

41
Malheureusement, cela ne rentrera pas dans les sous-répertoires.
Antimoine

4
Oui, * .cpp sera développé par le shell. clang a juste besoin d'une liste de fichiers. Des options plus avancées (comme le globbing récursif) dépendent des fonctionnalités de votre shell. Voir unix.stackexchange.com/questions/49913/recursive-glob pour savoir comment utiliser **construct.
sbarzowski

Et avec clang-tidy?
Aaron Franke

@AaronFranke Utiliser *.cpppour générer une liste de fichiers devrait fonctionner. La clang-tidycommande permet de passer plusieurs fichiers. `UTILISATION: clang-tidy [options] <source0> [... <sourceN>]` En pratique, ce n'est peut-être pas la meilleure solution. Clang-tidy effectue une analyse beaucoup plus approfondie, il nécessite donc les drapeaux du compilateur pour chaque fichier, etc. par-dessus. C'était il y a quelques années, il y a peut-être un meilleur moyen maintenant.
sbarzowski

85

Malheureusement, il n'existe aucun moyen d'appliquer le format clang de manière récursive. *.cppne correspondra qu'aux fichiers du répertoire courant, pas aux sous-répertoires. Même **/*ne fonctionne pas.

Heureusement, il existe une solution: saisissez tous les noms de fichiers avec la findcommande et indiquez-les. Par exemple, si vous souhaitez formater tous les fichiers .het tous les .cppfichiers du répertoire de foo/bar/manière récursive, vous pouvez faire

find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i

Voir ici pour une discussion supplémentaire.


6
Eh bien, **/*.cppsemble fonctionner en bash (raisonnablement moderne). Vous devrez peut-être shopt -s globstaravant.
sbarzowski

1
Si vous utilisez CMake, cet article vous montre comment utiliser CMake GLOB_RECURSEpour trouver tous les .cppfichiers et les transmettre clang-format.
phoenix

4
La combinaison de findet xargsdoit utiliser find ... -print0et xargs -0 ...pour garantir que tous les types de noms de fichiers sont gérés correctement.
Alexander le

3
Cette commande échoue si des fichiers .cpp ou .h existent dans pwd. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -irésoudra le problème.
nyanpasu64

26

Créez d'abord un .clang-formatfichier s'il n'existe pas:

clang-format -style=WebKit -dump-config > .clang-format

Choisissez le style prédéfini de votre choix ou modifiez le .clang-formatfichier résultant .

Le configurateur de format clang est utile.

Puis exécutez:

find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;

D' autres extensions de fichier que cpp, hpp, ccet cxxpeuvent être utilisés dans l'expression régulière, il suffit de les séparer par \|.


Car -style=fileexiste-t-il un moyen de spécifier un chemin de fichier personnalisé? J'ai essayé -style=~/.clang-formatet ça ne marche pas.
Aaron Franke

Pas que je sache, à part changer le répertoire actuel.
Alexander

La solution ghetto que j'ai trouvée est de créer une fonction qui exécute d'abord cp ~/.clang-format .la commande find dans votre réponse.
Aaron Franke

12

J'ai récemment trouvé un script bash qui fait exactement ce dont vous avez besoin:

https://github.com/eklitzke/clang-format-all

Il s'agit d'un script bash qui s'exécutera clang-format -isur votre code.

Fonctionnalités:

  • Trouve le bon chemin vers clang-formatUbuntu / Debian, qui encodent la version LLVM dans le clang-formatnom de fichier
  • Corrige les fichiers de manière récursive
  • Détecte les extensions de fichier les plus courantes utilisées par les projets C / C ++

Sous Windows, je l'ai utilisé avec succès dans Git Bash et WSL.


3

Pour les utilisateurs de Windows: Si vous avez la prise en charge de Powershell 3.0, vous pouvez faire:

Get-ChildItem -Path . -Directory -Recurse |
    foreach {
        cd $_.FullName
        &clang-format -i -style=WebKit *.cpp
    }

Remarque 1: utilisez pushd .et popdsi vous souhaitez avoir le même répertoire courant avant et après le script

Remarque 2: Le script fonctionne dans le répertoire de travail actuel

Note 3: Cela peut probablement être écrit sur une seule ligne si cela était vraiment important pour vous


0

J'utilise la commande suivante pour formater tous les fichiers objective-C sous le dossier actuel de manière récursive :

$ find . -name "*.m" -o -name "*.h" | sed 's| |\\ |g' | xargs clang-format -i

J'ai défini l'alias suivant dans mon .bash_profilepour faciliter les choses:

# Format objC files (*.h and *.m) under the current folder, recursively
alias clang-format-all="find . -name \"*.m\" -o -name \"*.h\" | sed 's| |\\ |g' | xargs clang-format -i"

0

Voici une solution qui recherche récursivement et dirige tous les fichiers au format clang sous forme de liste de fichiers en une seule commande. Il exclut également le répertoire "build" (j'utilise CMake), mais vous pouvez simplement omettre l'étape "grep" pour le supprimer.

shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i

0

Dans bash moderne, vous pouvez explorer de manière récursive l'arborescence des fichiers

for file_name in ./src/**/*.{cpp,h,hpp}; do
    if [ -f "$file_name" ]; then
        printf '%s\n' "$file_name"
        clang-format -i $file_name
    fi
done

Ici, la source est supposée se trouver dans ./srcet .clang-formatcontient les informations de formatage.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.