Jak wywołać clang-format w folderze projektu CPP?

87

Czy istnieje sposób na wywołanie czegoś podobnego clang-format --style=Webkitdo całego folderu projektu CPP, zamiast uruchamiania go osobno dla każdego pliku?

Używam clang-format.pyi vimrobię to, ale zakładam, że istnieje sposób na zastosowanie tego raz.

user3639557
źródło

Odpowiedzi:

46

Co powiesz na:

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

w folderze projektu. Opcja -i sprawia, że ​​jest on umieszczony w miejscu (domyślnie sformatowane wyjście jest zapisywane na standardowe wyjście).

sbarzowski
źródło
1
lub jeśli używasz pliku konfiguracyjnego i chcesz sformatować wiele typów plików: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos
41
Niestety, to się nie powtórzy w podkatalogach.
Antymon
4
Tak, * .cpp zostanie rozszerzony przez powłokę. clang potrzebuje tylko listy plików. Bardziej zaawansowane opcje (takie jak rekurencyjne globowanie) zależą od funkcji powłoki. Zobacz unix.stackexchange.com/questions/49913/recursive-glob, aby dowiedzieć się, jak używać **konstrukcji.
sbarzowski
A co z clang-tidy?
Aaron Franke
@AaronFranke Użycie *.cppdo wygenerowania listy plików powinno działać. clang-tidyKomenda umożliwia przepuszczenie wielu plików. `UŻYCIE: clang-tidy [opcje] <source0> [... <sourceN>]` Jednak w praktyce może to nie być najlepszy sposób. Clang-tidy wykonuje znacznie głębszą analizę, więc wymaga flag kompilatora dla każdego pliku itp. Kiedy używałem clang-tidy, zwykle miałem "bazę danych kompilacji" - plik JSON z poleceniami dla każdego pliku i skryptem ponad tym. To było kilka lat temu, może teraz jest lepszy sposób.
sbarzowski
85

Niestety, nie ma sposobu na rekurencyjne zastosowanie formatu clang. *.cppdopasuje tylko pliki w bieżącym katalogu, a nie podkatalogi. Nawet **/*nie działa.

Na szczęście jest rozwiązanie: pobierz wszystkie nazwy plików za pomocą findpolecenia i potokuj je. Na przykład, jeśli chcesz rekurencyjnie sformatować wszystkie pliki .hi .cpppliki w katalogu foo/bar/, możesz to zrobić

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

Zobacz tutaj, aby uzyskać dodatkową dyskusję.

Antymon
źródło
6
**/*.cppWydaje się , że działa w (dość nowoczesnym) bash. Być może będziesz musiał shopt -s globstarwcześniej.
sbarzowski
1
Jeśli używasz CMake, ten post pokazuje, jak możesz używać CMake GLOB_RECURSEdo znajdowania wszystkich .cppplików i przekazywania ich do clang-format.
phoenix
4
Połączenie findi xargspowinno używać find ... -print0i, xargs -0 ...aby upewnić się, że wszystkie typy nazw plików są obsługiwane poprawnie.
Aleksander
3
To polecenie kończy się niepowodzeniem, jeśli w pwd istnieją pliki .cpp lub .h. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -irozwiąże problem.
nyanpasu64
27

Najpierw utwórz .clang-formatplik, jeśli nie istnieje:

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

Wybierz dowolny predefiniowany styl, który lubisz, lub edytuj wynikowy .clang-formatplik.

pomocny jest konfigurator formatu clang .

Następnie uruchomić:

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

Pozostałe rozszerzenia plików niż cpp, hpp, cci cxxmogą być stosowane w wyrażeniu regularnym, tylko upewnij się, aby oddzielić je \|.

Aleksandra
źródło
Czy -style=fileistnieje sposób na określenie niestandardowej ścieżki do pliku? Próbowałem -style=~/.clang-formati to nie działa.
Aaron Franke
Nie żebym wiedział, poza zmianą bieżącego katalogu.
Alexander
Rozwiązanie getta, które wymyśliłem, polega na utworzeniu funkcji, która najpierw uruchamia cp ~/.clang-format .polecenie znajdź w twojej odpowiedzi.
Aaron Franke
12

Niedawno znalazłem skrypt basha, który robi dokładnie to, czego potrzebujesz:

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

To jest skrypt bash, który będzie działał clang-format -ina twoim kodzie.

Cechy:

  • Znajduje właściwą ścieżkę do clang-formatsystemu Ubuntu / Debian, który koduje wersję LLVM w clang-formatnazwie pliku
  • Naprawia pliki rekurencyjnie
  • Wykrywa najpopularniejsze rozszerzenia plików używane w projektach C / C ++

W systemie Windows z powodzeniem używałem go w Git Bash i WSL.

Julius Bullinger
źródło
3

Dla użytkowników systemu Windows: Jeśli masz obsługę Powershell 3.0, możesz:

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

Uwaga 1: Użyj pushd .i, popdjeśli chcesz mieć ten sam katalog bieżący przed i po skrypcie

Uwaga 2: skrypt działa w bieżącym katalogu roboczym

Uwaga 3: Prawdopodobnie można to zapisać w jednej linii, jeśli było to dla Ciebie naprawdę ważne

Tim Meyer
źródło
0

Używam następującego polecenia, aby rekurencyjnie formatować wszystkie pliki celu-C w bieżącym folderze :

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

.bash_profileDla ułatwienia zdefiniowałem następujący alias w moim :

# 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"
marcelosalloum
źródło
0

Oto rozwiązanie, które wyszukuje rekurencyjnie i przekierowuje wszystkie pliki do formatu clang jako listę plików w jednym poleceniu. Wyklucza również katalog „build” (ja używam CMake), ale możesz po prostu pominąć krok „grep”, aby go usunąć.

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

We współczesnym bashu możesz rekurencyjnie indeksować drzewo plików

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

W tym przypadku zakłada się, że źródło znajduje się w ./srci .clang-formatzawiera informacje o formatowaniu.

Michaił
źródło