是否有一种方法可以像这样调用clang-format --style=Webkit
来处理整个cpp项目文件夹,而不是单独为每个文件运行它?
我正在使用clang-format.py
和vim
来实现这一点,但我认为有一种方法可以一次性应用。
是否有一种方法可以像这样调用clang-format --style=Webkit
来处理整个cpp项目文件夹,而不是单独为每个文件运行它?
我正在使用clang-format.py
和vim
来实现这一点,但我认为有一种方法可以一次性应用。
很遗憾,目前没有办法递归地应用clang-format。在*.cpp
只会匹配当前目录下的文件,而不是子目录。即使使用**/*
也无效。
幸运的是,有一个解决方案:使用find
命令获取所有文件名并进行管道传输。例如,如果您想要递归地格式化目录foo/bar/
中的所有.h
和.cpp
文件,则可以执行以下操作:
find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i
请参阅此处,了解更多讨论。
**/*.cpp
可以工作。您可能需要在使用之前执行shopt -s globstar
。 - sbarzowskifind ... -print0
和xargs -0 ...
的组合可以确保正确处理所有类型的文件名。 - Alexander.cpp
或.h
文件,则该命令会失败。通过运行find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -i
来解决这个问题。 - nyanpasu64zsh
中也会失败。我实际上不明白为什么它在 bash 中不会失败。 :-) 这些引号应该真的存在,所以为什么在 bash 中没有它们也能工作呢? - Anne van Rossum怎么样:
clang-format -i -style=WebKit *.cpp *.h
在项目文件夹中。-i选项使其原地更改(默认情况下,格式化输出写入标准输出)。
clang-format-3.6 -i -style=file *.cpp *.h *.hpp
- mBardos*.cpp
生成文件列表应该是可行的。clang-tidy
命令允许传递多个文件。`
用法: clang-tidy [选项] <source0> [... <sourceN>]`
在实践中,这可能不是最好的方式。Clang-tidy执行更深入的分析,因此需要每个文件的编译器标志等。当我使用clang-tidy时,通常会有一个“编译数据库” - 一个JSON文件,其中包含每个文件的命令和一些脚本来处理它。那是几年前的事了,也许现在有更好的方法。 - sbarzowski如果不存在,首先创建一个.clang-format
文件:
clang-format -style=WebKit -dump-config > .clang-format
选择任何想要的预定义样式,或者编辑生成的.clang-format
文件。
clang-format配置工具是有帮助的。
然后运行:
find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;
正则表达式中可以使用除了 cpp
, hpp
, cc
, 和 cxx
之外的其他文件扩展名,只需用 \|
将它们分隔开即可。
-style=file
,是否有一种指定自定义文件路径的方法?我尝试了 -style=~/.clang-format
,但它没有起作用。 - Aaron Frankecp ~/.clang-format .
然后再运行你回答中的 find 命令。 - Aaron Frankefind -E . -regex '.*\.(cpp|hpp|cc|cxx)' -exec clang-format -style=file -i {} \;
- Anton Breusov-E
无法使用,但是-regextype egrep
可以。-regextype egrep
在macOS上也适用吗? - Alexander我最近发现了一段bash脚本,可以做到你需要的功能:
https://github.com/eklitzke/clang-format-all
这是一个bash脚本,它将在您的代码上运行
clang-format -i
。特点:
- 在Ubuntu / Debian上找到正确的
clang-format
路径,其中编码LLVM版本在clang-format
文件名中- 递归修复文件
- 检测C / C ++项目中使用最广泛的文件扩展名
在Windows上,我在Git Bash和WSL中成功使用了它。
对于Windows用户:如果您拥有Powershell 3.0支持,则可以执行以下操作:
Get-ChildItem -Path . -Directory -Recurse |
foreach {
cd $_.FullName
&clang-format -i -style=WebKit *.cpp
}
注意1:如果您想在脚本之前和之后保留相同的当前目录,请使用pushd .
和popd
注意2:该脚本会在当前工作目录中运行
注意3:如果真的很重要,那么这可以写成一行
当你在使用Windows(CMD)时,不想使用PowerShell大杀四方,可以尝试以下方法:
for /r %t in (*.cpp *.h) do clang-format -i -style=WebKit "%t"
如果在命令行脚本中,请不要忘记复制这两个%
。
clang-format
下载并安装。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
--style=file
的意思是我必须在同一级别上拥有一个自定义的.clang-format
clang-format指定文件,而我确实有这个文件。run_clang_format.sh
文件设置为可执行:chmod +x run_clang_format.sh
./run_clang_format.sh
~/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
您可以在我的run_clang_format.sh
文件中,找到我的eRCaGuy_PPM_Writer存储库和我的eRCaGuy_CodeFormatter存储库。我的.clang-format
文件也在那里。
run_clang_format.sh
文件
关于如何在我的 "git & Linux cmds, help, tips & tricks - Gabriel.txt" 文档中使用 clang-format
的笔记,请在我的 eRCaGuy_dotfiles 存储库中搜索 "clang-format"。clang-format
文档、设置和说明等!https://clang.llvm.org/docs/ClangFormat.html
在这里下载 Windows 版的 clang-format
自动格式化程序/代码检查器可执行文件,或其他安装程序/可执行文件:https://llvm.org/builds/
Clang-Format 样式选项:https://clang.llvm.org/docs/ClangFormatStyleOptions.html
[我的回答] 如何从 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
则包含格式化信息。git ls-files --exclude-standard
获取文件列表,因此未跟踪的文件会自动被跳过。它假定您在项目根目录下有一个.clang-tidy
文件。format:
ifeq ($(OS), Windows_NT)
pwsh -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
使用make format
命令来运行。
注意,在make中,我使用$$
转义$
符号。
如果你使用go-task而不是make,则需要执行以下操作:
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}}
使用task format
运行
如果您想运行单个脚本,则使用以下命令
# 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
shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i