117

有没有办法clang-format --style=Webkit为整个 cpp 项目文件夹调用类似的东西,而不是为每个文件单独运行它?

我正在使用clang-format.pyvim执行此操作,但我认为有一种方法可以应用一次。

4

12 回答 12

125

不幸的是,没有办法递归地应用 clang 格式。*.cpp只会匹配当前目录中的文件,不匹配子目录。甚至**/*不起作用。

幸运的是,有一个解决方案:使用find命令获取所有文件名并将它们通过管道输入。例如,如果您想递归格式化目录中的所有文件.h,您可以这样做.cppfoo/bar/

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

请参阅此处以获取更多讨论。

于 2016-03-16T21:08:36.387 回答
64

关于什么:

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

在项目文件夹中。-i 选项使其就地(默认情况下格式化输出被写入标准输出)。

于 2015-03-06T12:45:55.110 回答
41

.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,只需确保用 . 分隔它们即可。cccxx\|

于 2018-01-26T10:55:17.993 回答
14

我最近发现了一个 bash 脚本,它完全符合您的需要:

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

这是一个将clang-format -i在您的代码上运行的 bash 脚本。

特征:

  • 在 Ubuntu/Debian 上找到正确的路径,在文件名clang-format中编码 LLVM 版本clang-format
  • 递归修复文件
  • 检测 C/C++ 项目使用的最常见的文件扩展名

在 Windows 上,我在 Git Bash 和 WSL 中成功使用了它。

于 2017-11-14T14:53:33.923 回答
9

对于 Windows 用户:如果您有 Powershell 3.0 支持,您可以执行以下操作:

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

注意1:如果你想在脚本之前和之后拥有相同的当前目录,请使用pushd .andpopd

注2:脚本在当前工作目录下运行

注意3:如果这对您真的很重要,这可能会写在一行中

于 2019-05-16T14:06:46.573 回答
8

当您使用 Windows (CMD) 但不想使用 PowerShell 大炮射击这只苍蝇时,试试这个:

for /r %t in (*.cpp *.h) do clang-format -i -style=WebKit "%t"

不要忘记%在 cmd 脚本中复制两个 s if 。

于 2021-01-27T11:09:37.670 回答
4

下面的脚本和过程:

  1. Linux中工作
  2. 应该在MacOS上工作
  3. Git For Windows终端中的Windows中工作,下载并安装.clang-format

这是我的做法:

我创建了一个run_clang_format.sh脚本并将其放在我的项目目录的根目录中,然后我从任何地方运行它。这是它的样子:

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 格式说明符文件,我这样做了。

现在,使您新创建的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

您可以在我的eRCaGuy_PPM_Writer存储库和我的eRCaGuy_CodeFormatterrun_clang_format.sh存储库中找到我的文件。我的文件也在那里.clang-format

参考:

  1. 我的存储库:
    1. eRCaGuy_PPM_Writer 存储
    2. run_clang_format.sh文件
  2. 我关于如何clang-format在我的 eRCaGuy_dotfiles 存储库中的“git & Linux cmds、帮助、提示和技巧 - Gabriel.txt”文档中使用的注释(在文档中搜索“clang-format”)。
  3. 官方clang-format文档、设置、说明等!https://clang.llvm.org/docs/ClangFormat.html
  4. 在此处下载clang-format适用于 Windows 的自动格式化程序/linter 可执行文件或其他安装程序/可执行文件:https ://llvm.org/builds/
  5. Clang 格式样式选项:https ://clang.llvm.org/docs/ClangFormatStyleOptions.html
  6. [我的回答]如何从脚本本身中获取 Bash 脚本的源目录?

有关的:

  1. [我的回答]使用 clang 格式缩进预处理器指令

也可以看看:

  1. [我的回答] https://stackoverflow.com/questions/67678531/fixing-a-simple-c-code-without-the-comments/67678570#67678570
于 2021-02-01T07:02:27.587 回答
1

我正在使用以下命令递归地格式化当前文件夹下的所有 Objective-C 文件:

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

我在 my 中定义了以下别名.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"
于 2019-07-18T19:01:41.950 回答
1

这是一种递归搜索并将所有文件通过管道传输到 clang-format 作为一个命令中的文件列表的解决方案。它还排除了“build”目录(我使用 CMake),但您可以省略“grep”步骤来删除它。

shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i
于 2020-04-11T12:56:53.470 回答
1

在现代 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包含格式信息。

于 2020-11-15T23:51:15.127 回答
0

正如@sbarzowski 在上面的评论中提到的那样,在 bash 中,您可以启用globstar导致**递归扩展。

如果您只想要这个命令,您可以执行以下操作来格式化所有.h,.cc.cpp文件。

(shopt -s globstar; clang-format -i **/*.{h,cc,cpp})

或者你可以在 bash中添加shopt -s globstar你的内容.bashrc并一直保持良好状态。**

作为旁注,您可能希望--dry-run第一次使用 clang-format 以确保它是您想要的。

于 2021-12-23T18:59:37.197 回答
0

您可以在 Make 文件中使用它。它用于git ls-files --exclude-standard获取文件列表,这意味着自动跳过未跟踪的文件。它假定您.clang-tidy在项目根目录中有一个文件。

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

运行make format

$请注意,我使用$$for 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
于 2022-02-04T22:10:47.990 回答