Is er een manier om iets als clang-format --style=Webkit
aan te roepen voor een hele cpp-projectmap, in plaats van het apart uit te voeren voor elk bestand?
Ik gebruik clang-format.py
en vim
om dit te doen, maar ik neem aan dat er een manier is om dit eenmalig toe te passen.
Antwoord 1, autoriteit 100%
Helaas is er geen manier om clang-formaat recursief toe te passen. *.cpp
komt alleen overeen met bestanden in de huidige map, niet met submappen. Zelfs **/*
werkt niet.
Gelukkig is er een oplossing: pak alle bestandsnamen met de opdracht find
en pijp ze erin. Als u bijvoorbeeld alle .h
en .cpp
bestanden in de directory foo/bar/
recursief, kunt u doen
find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i
Zie hiervoor aanvullende discussie.
Antwoord 2, autoriteit 52%
Hoe zit het met:
clang-format -i -style=WebKit *.cpp *.h
in de projectmap. De -i optie zorgt ervoor dat het op zijn plaats zit (standaard wordt geformatteerde uitvoer naar stdout geschreven).
Antwoord 3, autoriteit 33%
Maak eerst een .clang-format
bestand als het niet bestaat:
clang-format -style=WebKit -dump-config > .clang-format
Kies de vooraf gedefinieerde stijl die je leuk vindt, of bewerk het resulterende bestand .clang-format
.
clang-format configuratoris handig.
Voer vervolgens uit:
find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;
Andere bestandsextensies dan cpp
, hpp
, cc
en cxx
kunnen in de reguliere expressie worden gebruikt, zorg ervoor dat u ze scheidt met \|
.
Antwoord 4, autoriteit 11%
Ik heb onlangs een bash-script gevonden dat precies doet wat je nodig hebt:
https://github.com/eklitzke/clang-format-all
Dit is een bash-script dat
clang-format -i
op je code uitvoert.Kenmerken:
- Vindt het juiste pad naar
clang-format
op Ubuntu/Debian, die de LLVM-versie codeert in de bestandsnaamclang-format
- Repareert bestanden recursief
- Detecteert de meest voorkomende bestandsextensies die worden gebruikt door C/C++-projecten
In Windows heb ik het met succes gebruikt in Git Bash en WSL.
Antwoord 5, autoriteit 7%
Voor de Windows-gebruikers: als je Powershell 3.0-ondersteuning hebt, kun je het volgende doen:
Get-ChildItem -Path . -Directory -Recurse |
foreach {
cd $_.FullName
&clang-format -i -style=WebKit *.cpp
}
Opmerking1: Gebruik pushd .
en popd
als u dezelfde huidige map voor en na het script wilt hebben
Opmerking2: Het script werkt in de huidige werkmap
Opmerking 3: Dit kan waarschijnlijk in één regel worden geschreven als dat echt belangrijk voor je was
Antwoord 6, autoriteit 7%
Als je Windows (CMD) gebruikt maar het PowerShell-kanon niet wilt gebruiken om deze vlieg af te schieten, probeer dan dit:
for /r %t in (*.cpp *.h) do clang-format -i -style=WebKit "%t"
Vergeet niet om de twee %
s te dupliceren als in een cmd-script.
Antwoord 7, autoriteit 3%
Het onderstaande script en proces:
- werkt in Linux
- zou moeten werken op MacOS
- werkt in Windowsbinnen Git For Windowsterminal met
clang-format
gedownload en geïnstalleerd.
Zo doe ik het:
Ik maak een run_clang_format.sh
-script en plaats het in de hoofdmap van mijn projectdirectory, dan voer ik het overal uit. Zo ziet het eruit:
run_clang_format.sh
#!/bin/bash
THIS_PATH="$(realpath "$0")"
THIS_DIR="$(dirname "$THIS_PATH")"
# Find all files in THIS_DIR which end in .ino, .cpp, etc., as specified
# in the regular expression just below
FILE_LIST="$(find "$THIS_DIR" | grep -E ".*(\.ino|\.cpp|\.c|\.h|\.hpp|\.hh)$")"
echo -e "Files found to format = \n\"\"\"\n$FILE_LIST\n\"\"\""
# Format each file.
# - NB: do NOT put quotes around `$FILE_LIST` below or else the `clang-format` command will
# mistakenly see the entire blob of newline-separated file names as a SINGLE file name instead
# of as a new-line separated list of *many* file names!
clang-format --verbose -i --style=file $FILE_LIST
Het gebruik van --style=file
betekent dat ik ook een aangepast .clang-format
clang-format specificatiebestand op hetzelfde niveau moet hebben, wat ik doe.
Maak nu uw nieuw gemaakte run_clang_format.sh
-bestand uitvoerbaar:
chmod +x run_clang_format.sh
…en voer het uit:
./run_clang_format.sh
Hier is een voorbeeldrun en uitvoer voor mij:
~/GS/dev/eRCaGuy_PPM_Writer$ ./run_clang-format.sh
Files found to format =
"""
/home/gabriel/GS/dev/eRCaGuy_PPM_Writer/examples/PPM_Writer_demo/PPM_Writer_demo.ino
/home/gabriel/GS/dev/eRCaGuy_PPM_Writer/examples/PPM_Writer_demo2/PPM_Writer_demo2.ino
/home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/eRCaGuy_PPM_Writer.h
/home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/eRCaGuy_PPM_Writer.cpp
/home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/timers/eRCaGuy_TimerCounterTimers.h
"""
Formatting /home/gabriel/GS/dev/eRCaGuy_PPM_Writer/examples/PPM_Writer_demo/PPM_Writer_demo.ino
Formatting /home/gabriel/GS/dev/eRCaGuy_PPM_Writer/examples/PPM_Writer_demo2/PPM_Writer_demo2.ino
Formatting /home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/eRCaGuy_PPM_Writer.h
Formatting /home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/eRCaGuy_PPM_Writer.cpp
Formatting /home/gabriel/GS/dev/eRCaGuy_PPM_Writer/src/timers/eRCaGuy_TimerCounterTimers.h
Je kunt mijn run_clang_format.sh
-bestand in mijn eRCaGuy_PPM_Writer-repository en in mijn eRCaGuy_CodeFormatterrepository ook. Mijn .clang-format
-bestand is er ook.
Referenties:
- Mijn opslagplaats:
- Mijn opmerkingen over het gebruik van
clang-format
in mijn “git & Linux cmds, help, tips & tricks – Gabriel.txt”document in mijn eRCaGuy_dotfilesrepo (zoek het document op “clang-format”). - Officiële
clang-format
documentatie, setup, instructies, etc! https://clang.llvm.org/docs/ClangFormat.html - Download het
clang-format
auto-formatter/linter uitvoerbaar bestand voor Windows, of andere installatieprogramma’s/uitvoerbare bestanden hier: https://llvm.org/builds/ - Clang-Format-stijlopties: https://clang.llvm.org/docs/ClangFormatStyleOptions .html
- [mijn antwoord] Hoe kan ik de brondirectory van een Bash-script uit het script zelf halen?
Gerelateerd:
- [mijn antwoord] Preprocessor-richtlijnen inspringen met clang-formaat
Zie ook:
- [mijn antwoord] https://stackoverflow .com/questions/67678531/fixing-a-simple-c-code-without-the-coments/67678570#67678570
Antwoord 8
Ik gebruik de volgende opdracht om alle objective-C-bestanden onder de huidige map recursiefop te maken:
$ find . -name "*.m" -o -name "*.h" | sed 's| |\\ |g' | xargs clang-format -i
Ik heb de volgende alias gedefinieerd in mijn .bash_profile
om dingen gemakkelijker te maken:
# 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"
Antwoord 9
Hier is een oplossing die recursief zoekt en alle bestanden in één commando naar clang-formaat stuurt als een bestandslijst. Het sluit ook de map “build” uit (ik gebruik CMake), maar je kunt de stap “grep” gewoon weglaten om die te verwijderen.
shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i
Antwoord 10
In moderne bash kun je recursief de bestandsstructuur crawlen
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
Hier wordt aangenomen dat de bron zich in ./src
bevindt en het .clang-format
bevat de opmaakinformatie.
Antwoord 11
Zoals @sbarzowski in een opmerking hierboven aangeeft, kun je in bash globstarwaardoor **
recursief uitbreidt.
Als je het alleen voor deze ene opdracht wilt, kun je zoiets als het volgende doen om alle .h
, .cc
en .cpp
bestanden.
(shopt -s globstar; clang-format -i **/*.{h,cc,cpp})
Of je kunt shopt -s globstar
toevoegen aan je .bashrc
en de hele tijd **
goedheid hebben in bash.
Als een kanttekening, wil je misschien de eerste keer --dry-run
met clang-formaat gebruiken om er zeker van te zijn dat het is wat je wilt.
Antwoord 12
U kunt dit gebruiken in een Make-bestand. Het gebruikt git ls-files --exclude-standard
om de lijst met bestanden te krijgen, dus dat betekent dat niet-getrackte bestanden automatisch worden overgeslagen. Het gaat ervan uit dat je een .clang-tidy
-bestand in de hoofdmap van je project hebt.
format:
ifeq ($(OS), Windows_NT)
powershell -c '$$files=(git ls-files --exclude-standard); foreach ($$file in $$files) { if ((get-item $$file).Extension -in ".cpp", ".hpp", ".c", ".cc", ".cxx", ".hxx", ".ixx") { clang-format -i -style=file $$file } }'
else
git ls-files --exclude-standard | grep -E '\.(cpp|hpp|c|cc|cxx|hxx|ixx)$$' | xargs clang-format -i -style=file
endif
Uitvoeren met make format
Merk op dat ik ontsnapt ben aan $
met $$
voor make.
Als je go-task gebruikt in plaats van make, heb je dit nodig:
format:
- |
{{if eq OS "windows"}}
powershell -c '$files=(git ls-files --exclude-standard); foreach ($file in $files) { if ((get-item $file).Extension -in ".cpp", ".hpp", ".c", ".cc", ".cxx", ".hxx", ".ixx") { clang-format -i -style=file $file } }'
{{else}}
git ls-files --exclude-standard | grep -E '\.(cpp|hpp|c|cc|cxx|hxx|ixx)$' | xargs clang-format -i -style=file
{{end}}
Uitvoeren met task format
Als je de afzonderlijke scripts wilt uitvoeren, gebruik dan deze
# powershell
$files=(git ls-files --exclude-standard); foreach ($file in $files) { if ((get-item $file).Extension -in ".cpp", ".hpp", ".c", ".cc", ".cxx", ".hxx", ".ixx") { clang-format -i -style=file $file } }
# bash
git ls-files --exclude-standard | grep -E '\.(cpp|hpp|c|cc|cxx|hxx|ixx)$' | xargs clang-format -i -style=file