ClangFormat¶
ClangFormat 描述了一组基于 LibFormat 的工具。它可以通过各种方式支持您的工作流程,包括独立工具和编辑器集成。
独立工具¶
clang-format 位于 clang/tools/clang-format 中,可用于格式化 C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# 代码。
$ clang-format --help
OVERVIEW: A tool to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code.
If no arguments are specified, it formats the code from standard input
and writes the result to the standard output.
If <file>s are given, it reformats the files. If -i is specified
together with <file>s, the files are edited in-place. Otherwise, the
result is written to the standard output.
USAGE: clang-format [options] [@<file>] [<file> ...]
OPTIONS:
Clang-format options:
--Werror - If set, changes formatting warnings to errors
--Wno-error=<value> - If set don't error out on the specified warning type.
=unknown - If set, unknown format options are only warned about.
This can be used to enable formatting, even if the
configuration contains unknown (newer) options.
Use with caution, as this might lead to dramatically
differing format depending on an option being
supported or not.
--assume-filename=<string> - Set filename used to determine the language and to find
.clang-format file.
Only used when reading from stdin.
If this is not passed, the .clang-format file is searched
relative to the current working directory when reading stdin.
Unrecognized filenames are treated as C++.
supported:
CSharp: .cs
Java: .java
JavaScript: .mjs .js .ts
Json: .json
Objective-C: .m .mm
Proto: .proto .protodevel
TableGen: .td
TextProto: .txtpb .textpb .pb.txt .textproto .asciipb
Verilog: .sv .svh .v .vh
--cursor=<uint> - The position of the cursor when invoking
clang-format from an editor integration
--dry-run - If set, do not actually make the formatting changes
--dump-config - Dump configuration options to stdout and exit.
Can be used with -style option.
--fail-on-incomplete-format - If set, fail with exit code 1 on incomplete format.
--fallback-style=<string> - The name of the predefined style used as a
fallback in case clang-format is invoked with
-style=file, but can not find the .clang-format
file to use. Defaults to 'LLVM'.
Use -fallback-style=none to skip formatting.
--ferror-limit=<uint> - Set the maximum number of clang-format errors to emit
before stopping (0 = no limit).
Used only with --dry-run or -n
--files=<filename> - A file containing a list of files to process, one per line.
-i - Inplace edit <file>s, if specified.
--length=<uint> - Format a range of this length (in bytes).
Multiple ranges can be formatted by specifying
several -offset and -length pairs.
When only a single -offset is specified without
-length, clang-format will format up to the end
of the file.
Can only be used with one input file.
--lines=<string> - <start line>:<end line> - format a range of
lines (both 1-based).
Multiple ranges can be formatted by specifying
several -lines arguments.
Can't be used with -offset and -length.
Can only be used with one input file.
-n - Alias for --dry-run
--offset=<uint> - Format a range starting at this byte offset.
Multiple ranges can be formatted by specifying
several -offset and -length pairs.
Can only be used with one input file.
--output-replacements-xml - Output replacements as XML.
--qualifier-alignment=<string> - If set, overrides the qualifier alignment style
determined by the QualifierAlignment style flag
--sort-includes - If set, overrides the include sorting behavior
determined by the SortIncludes style flag
--style=<string> - Set coding style. <string> can be:
1. A preset: LLVM, GNU, Google, Chromium, Microsoft,
Mozilla, WebKit.
2. 'file' to load style configuration from a
.clang-format file in one of the parent directories
of the source file (for stdin, see --assume-filename).
If no .clang-format file is found, falls back to
--fallback-style.
--style=file is the default.
3. 'file:<format_file_path>' to explicitly specify
the configuration file.
4. "{key: value, ...}" to set specific parameters, e.g.:
--style="{BasedOnStyle: llvm, IndentWidth: 8}"
--verbose - If set, shows the list of processed files
Generic Options:
--help - Display available options (--help-hidden for more)
--help-list - Display list of available options (--help-list-hidden for more)
--version - Display the version of this program
当所需的代码格式化样式与可用选项不同时,可以使用 -style="{key: value, ...}"
选项自定义样式,或者将您的样式配置放在项目目录中的 .clang-format
或 _clang-format
文件中,并使用 clang-format -style=file
。
创建 .clang-format
文件的一种简单方法是
clang-format -style=llvm -dump-config > .clang-format
可用的样式选项在 Clang-Format 样式选项 中进行了描述。
.clang-format-ignore¶
您可以创建 .clang-format-ignore
文件,以使 clang-format
忽略某些文件。 .clang-format-ignore
文件包含文件路径名的模式。它具有以下格式
空行将被跳过。
每行的开头和结尾的空格将被修剪。
以井号 (
#
) 开头的行是注释。非注释行是一个模式。
斜杠 (
/
) 用作目录分隔符。模式相对于
.clang-format-ignore
文件的目录(如果模式以斜杠开头,则相对于根目录)。包含驱动器名的模式(例如C:
)不受支持。模式遵循 POSIX 2.13.1、2.13.2 和 2.13.3 的规则 1 中指定的规则。
如果模式以感叹号 (
!
) 开头,则该模式会被否定。
要匹配目录中的所有文件,请使用例如 foo/bar/*
。要匹配 .clang-format-ignore
文件目录中的所有文件,请使用 *
。支持多个 .clang-format-ignore
文件,类似于 .clang-format
文件,较低级别的目录文件将覆盖较高级别的目录文件。
Vim 集成¶
有一个 vim 集成,允许您在当前缓冲区上运行 clang-format 独立工具,可以选择要重新格式化的区域。
此集成采用 python 文件的形式,可以在 clang/tools/clang-format/clang-format.py 中找到。
if has('python')
map <C-K> :pyf <path-to-this-file>/clang-format.py<cr>
imap <C-K> <c-o>:pyf <path-to-this-file>/clang-format.py<cr>
elseif has('python3')
map <C-K> :py3f <path-to-this-file>/clang-format.py<cr>
imap <C-K> <c-o>:py3f <path-to-this-file>/clang-format.py<cr>
endif
这可以通过在您的 .vimrc 中添加以下内容来集成
第一行在 NORMAL 和 VISUAL 模式下启用 clang-format,第二行添加了对 INSERT 模式的支持。如果您需要在不同的键上使用 clang-format,请将“C-K”更改为其他绑定(C-K 代表 Ctrl+k)。
使用此集成,您可以在绑定键上按下,clang-format 将在 NORMAL 和 INSERT 模式下格式化当前行,或者在 VISUAL 模式下格式化选定的区域。行或区域将扩展到下一个较大的语法实体。
它操作当前(可能是未保存的)缓冲区,并且不会创建或保存任何文件。要恢复格式,只需撤消。
function! Formatonsave()
let l:formatdiff = 1
pyf <path-to-this-file>/clang-format.py
endfunction
autocmd BufWritePre *.h,*.cc,*.cpp call Formatonsave()
另一种选择是在保存文件时格式化更改,从而将集成到编码工作流程中。为此,请将以下内容添加到您的 .vimrc 中
Emacs 集成¶
(load "<path-to-clang>/tools/clang-format/clang-format.el")
(global-set-key [C-M-tab] 'clang-format-region)
与 vim 的集成类似,还存在 emacs 的集成。它可以在 clang/tools/clang-format/clang-format.el 中找到,可以通过在您的 .emacs 中添加以下内容来使用
这将 clang-format-region 函数绑定到 C-M-tab,然后它将格式化当前行或选定的区域。
BBEdit 集成¶
clang-format 不能用作 BBEdit 的文本过滤器,但可以通过脚本很好地工作。用于执行此集成的 AppleScript 可以在 clang/tools/clang-format/clang-format-bbedit.applescript 中找到;将副本放在 ~/Library/Application Support/BBEdit/Scripts 中,并编辑其中的路径以指向您的 clang-format 的本地副本。
使用此集成,您可以从脚本菜单中选择脚本,clang-format 将格式化选择内容。请注意,您可以通过重命名脚本重命名菜单项,并可以在 BBEdit 首选项(在菜单和快捷方式下)中为菜单项分配键盘快捷键。
CLion 集成¶
clang-format 集成到 CLion 中,作为一种可选的代码格式化程序。当项目根目录下存在 .clang-format
文件时,CLion 会自动启用它。代码样式规则在您键入时应用,包括缩进、自动完成、代码生成和重构。
clang-format 也可以在没有 .clang-format
文件的情况下启用。在这种情况下,CLion 会提示您根据当前 IDE 设置或默认 LLVM 样式创建一个。
Visual Studio 集成¶
从 alpha 构建站点 下载最新的 Visual Studio 扩展。默认的按键绑定是 Ctrl-R,Ctrl-F。
Visual Studio Code 集成¶
从 Visual Studio Marketplace 获取最新的 Visual Studio Code 扩展。默认的按键绑定是 Alt-Shift-F。
Git 集成¶
% git clang-format -h
usage: git clang-format [OPTIONS] [<commit>] [<commit>|--staged] [--] [<file>...]
If zero or one commits are given, run clang-format on all lines that differ
between the working directory and <commit>, which defaults to HEAD. Changes are
only applied to the working directory, or in the stage/index.
Examples:
To format staged changes, i.e everything that's been `git add`ed:
git clang-format
To also format everything touched in the most recent commit:
git clang-format HEAD~1
If you're on a branch off main, to format everything touched on your branch:
git clang-format main
If two commits are given (requires --diff), run clang-format on all lines in the
second <commit> that differ from the first <commit>.
The following git-config settings set the default of the corresponding option:
clangFormat.binary
clangFormat.commit
clangFormat.extensions
clangFormat.style
positional arguments:
<commit> revision from which to compute the diff
<file>... if specified, only consider differences in these files
optional arguments:
-h, --help show this help message and exit
--binary BINARY path to clang-format
--commit COMMIT default commit to use if none is specified
--diff print a diff instead of applying the changes
--diffstat print a diffstat instead of applying the changes
--extensions EXTENSIONS
comma-separated list of file extensions to format, excluding the period and case-insensitive
-f, --force allow changes to unstaged files
-p, --patch select hunks interactively
-q, --quiet print less information
--staged, --cached format lines in the stage instead of the working dir
--style STYLE passed to clang-format
-v, --verbose print extra information
脚本 clang/tools/clang-format/git-clang-format 可用于格式化 git 提交中修改的代码行
用于补丁重新格式化的脚本¶
usage: clang-format-diff.py [-h] [-i] [-p NUM] [-regex PATTERN] [-iregex PATTERN] [-sort-includes] [-v] [-style STYLE]
[-fallback-style FALLBACK_STYLE] [-binary BINARY]
This script reads input from a unified diff and reformats all the changed
lines. This is useful to reformat all the lines touched by a specific patch.
Example usage for git/svn users:
git diff -U0 --no-color --relative HEAD^ | clang-format-diff.py -p1 -i
svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
It should be noted that the filename contained in the diff is used unmodified
to determine the source file to update. Users calling this script directly
should be careful to ensure that the path in the diff is correct relative to the
current working directory.
optional arguments:
-h, --help show this help message and exit
-i apply edits to files instead of displaying a diff
-p NUM strip the smallest prefix containing P slashes
-regex PATTERN custom pattern selecting file paths to reformat (case sensitive, overrides -iregex)
-iregex PATTERN custom pattern selecting file paths to reformat (case insensitive, overridden by -regex)
-sort-includes let clang-format sort include blocks
-v, --verbose be more verbose, ineffective without -i
-style STYLE formatting style to apply (LLVM, GNU, Google, Chromium, Microsoft, Mozilla, WebKit)
-fallback-style FALLBACK_STYLE
The name of the predefined style used as a fallback in case clang-format is invoked with-style=file, but can not
find the .clang-formatfile to use.
-binary BINARY location of binary to use for clang-format
python 脚本 clang/tools/clang-format/clang-format-diff.py 解析统一差异的输出,并使用 clang-format 重新格式化所有包含的代码行。
hg diff -U0 --color=never | clang-format-diff.py -i -p1
要重新格式化最新 Mercurial/hg 提交中的所有代码行,请执行以下操作
选项 -U0 将创建一个没有上下文行的差异(脚本也会格式化这些上下文行)。