Як викликати clang-формат через папку проекту cpp?


87

Чи є спосіб викликати щось на зразок clang-format --style=Webkitцілої папки проекту cpp, а не запускати його окремо для кожного файлу?

Я використовую clang-format.pyі vimдля цього, але я припускаю, що є спосіб застосувати це один раз.

Відповіді:


46

Що стосовно:

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

у папці проекту. Параметр -i робить це місцем (за замовчуванням відформатований вивід записується в stdout).


1
або якщо ви використовуєте конфігураційний файл і хочете відформатувати кілька типів файлів: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos

41
На жаль, це не повториться у підкаталоги.
Сурма

4
Так, * .cpp буде розширено оболонкою. clang просто потрібен список файлів. Більш розширені параметри (наприклад, рекурсивне глобулювання) залежать від особливостей вашої оболонки. Дивіться unix.stackexchange.com/questions/49913/recursive-glob про те, як використовувати **конструкцію.
sbarzowski

Що з clang-tidy?
Аарон Франке,

@AaronFranke Використання *.cppдля створення списку файлів має спрацювати. clang-tidyКоманда дозволяє передачу кількох файлів. `ВИКОРИСТАННЯ: clang-tidy [options] <source0> [... <sourceN>]` `На практиці це може бути не найкращим способом. Clang-tidy виконує набагато глибший аналіз, тому для кожного файлу потрібні прапори компілятора і т. Д. Коли я використовував clang-tidy, я зазвичай мав "базу даних компіляції" - файл JSON із командами для кожного файлу та деяким скриптом над ним. Це було пару років тому, можливо, зараз є кращий спосіб.
sbarzowski

85

На жаль, немає можливості застосувати clang-формат рекурсивно. *.cppбуде відповідати лише файлам у поточному каталозі, а не підкаталогам. Навіть **/*не працює.

На щастя, є рішення: захопіть усі імена файлів за допомогою findкоманди та передайте їх. Наприклад, якщо ви хочете рекурсивно форматувати всі .hта .cppфайли в каталозі foo/bar/, ви можете

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

Дивіться тут для додаткового обговорення.


6
Ну, **/*.cppсхоже, це працює в (досить сучасному) bash. Можливо, вам доведеться shopt -s globstarраніше.
sbarzowski

1
Якщо ви використовуєте CMake, у цій публікації показано, як за допомогою CMake GLOB_RECURSEможна знайти всі .cppфайли та передати їх clang-format.
Фенікс

4
Комбінація findі xargsповинна використовувати find ... -print0та xargs -0 ...забезпечувати правильну обробку всіх типів імен файлів.
Олександр

3
Ця команда не вдається, якщо в pwd існують файли .cpp або .h. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -iвирішить проблему.
nyanpasu64

27

Спочатку створіть .clang-formatфайл, якщо він не існує:

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

Виберіть будь-який попередньо визначений стиль, який вам подобається, або відредагуйте отриманий .clang-formatфайл.

Конфігуратор у форматі clang корисний.

Потім запустіть:

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

Інші розширення файлів , ніж cpp, hpp, ccі cxxможе бути використаний в регулярному виразі, просто переконайтеся , що відокремити їх \|.


Бо -style=fileчи є спосіб вказати власний шлях до файлу? Я намагався, -style=~/.clang-formatі це не працює.
Аарон Франке

Не те, що я знаю, крім зміни поточного каталогу.
Олександр

Гетто-рішення, яке я придумав, полягає у створенні функції, яка спочатку запускається, cp ~/.clang-format .а потім команда find у вашій відповіді.
Аарон Франке

12

Нещодавно я знайшов bash-скрипт, який робить саме те, що вам потрібно:

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

Це скрипт bash, який буде працювати clang-format -iна вашому коді.

Особливості:

  • Знаходить правильний шлях до clang-formatUbuntu / Debian, який кодує версію LLVM в clang-formatназві файлу
  • Виправляє файли рекурсивно
  • Виявляє найпоширеніші розширення файлів, що використовуються проектами C / C ++

У Windows я успішно використовував його в Git Bash та WSL.


3

Для користувачів Windows: Якщо у вас є підтримка Powershell 3.0, ви можете зробити:

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

Примітка 1. Використовуйте pushd .і, popdякщо ви хочете мати однаковий поточний каталог до і після сценарію

Примітка2: Скрипт працює в поточному робочому каталозі

Примітка3: Це, можливо, можна написати в один рядок, якщо це було для вас дійсно важливим


0

Я використовую таку команду для рекурсивного форматування всіх файлів об’єкта-C у поточній папці :

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

.bash_profileДля полегшення ситуації я визначив наступний псевдонім :

# 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

Ось рішення, яке здійснює рекурсивний пошук та передає всі файли у формат clang як список файлів за допомогою однієї команди. Він також виключає каталог "build" (я використовую CMake), але ви можете просто опустити крок "grep", щоб видалити це.

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

0

У сучасному bash ви можете рекурсивно сканувати дерево файлів

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

Тут передбачається, що джерело знаходиться в ./srcі .clang-formatмістить інформацію про форматування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.